Menü bei OnClick

Micka

Micka

Fortgeschrittenes Mitglied
1
Hy,

ich arbeite gerade an einer App die unter anderem eine Activity besitzt, die ListActivity implementiert. Mittels eigenem ListAdapter ist es mir bereits gelungen die Daten für die Liste aus einer Datenbank zu lesen.

So weit so gut.

Mein Wunsch ist es nun das sich ein Menü(meinetwegen ein KontextMenu) öffnet wenn man auf eines der Elemente(Alles TextViews) des ListView klickt.

Mit einem normalen KontextMenu bin ich nicht weit gekommen. Problem dabei ist das ich in der Methode
Code:
public boolean onContextItemSelected(MenuItem item)
nicht mehr auf die ID der Datenbankzeile zugreifen kann aus der das item ursprünglich kam.

Also habe ich mir gedacht ich setze einfach im Layout der Listview bei den einzelnen Views das folgende Attribut.
Code:
android:onClick="beliebigeOnClickMethode"
Nachdem der eigeneListAdapter die Textviews dann mit ihrem Inhalt aus der Datenbank befüllt hat setze ich per
Code:
setID()
noch schnell die ID des Textviews auf die ID der Datenbankzeile.

nun könnte ich in meiner Activity in der Methode bequem auf die Id zugreifen.

Beispiel:
Code:
public void beliebigeOnClickMethode(View v)
{
    Textview textview = (Textview) view;
    int id = textview.getID();
}
damit könnte ich nun arbeiten um z.B: in der Datenbank eine Zeile zu löschen oder zu ändern. Aber eben das oder ist das Problem.

Wie kriege ich ein Menü hin das nun zwischen den zwei Fällen(EDIT, DELETE) entscheidet?

Das normale OptionsMenü der Activity scheidet aus da es bereits anderweitig genutzt ist.
 
du kannst mittels meniiteminfo auf die position der geklickten zeile innerhalb deiner onContextItemSelected zugreifen.

such mal danach
 
  • Danke
Reaktionen: Micka
okay, werd mir das mal raussuchen. Einen eigenen Menüartigen Dialog in der onClickMethode kann ich nicht erzeugen oder gibt es dafür auch eine Möglichkeit?
 
Mir ist gerade eine eventuelle Lösung mittels Kontextmenü eingefallen.
Der List Adapter nutzt ja eine ArrayList. Wenn ich ihm nun eine angepasste ArrayList gebe kann ich mir getItemId so implementieren das die DatenbankId returned wird. Werde mal sehen was ich später noch hinkriege.
 
ich sag dir ja - du kannst ein contextmenu implementieren, dort über menuiteminfo die position des geklickten finden und dann vom adapter laden.

registerForContextMenu(listview); nicht vergessen
 
  • Danke
Reaktionen: Micka
Ich hab gerade in der S-Bahn nochmal gegoogelt und folgendes gefunden.
ContextMenü mit ListView verbinden und Daten übergeben. - Tutorials & FAQs - Android-Developers
Es scheint also eine Lösung für mein Problem zu geben. Allerdings verstehe ich an dieser Lösung einiges nicht, ohne es zu verstehen will ich es nicht implementieren.

Was bewirkt startManagingCursor z.B.,

Desweiteren ist mir mit einem simpleCursorAdapter nicht geholfen. Ich müsste das ganze auf meinen Code anpassen.

Kann jemand von euch den gesamten Code nachvollziehen?
 
Also hier ist erstmal was "startManagingCursor" tut
Activity | Android Developers

und deine Frage aus dem ersten Post verstehe ich nicht so ganz, zu den ContextMenus gibt es doch die onContextItemSelected(MenuItem item), da kannst du doch dann wieder ganz einfach unterscheiden welche Option im Kontextmenü gewählt wurde.

Beantwortet das deine Frage? oder was wolltest du wissen?
 
  • Danke
Reaktionen: Micka
Micka schrieb:
Ich hab gerade in der S-Bahn nochmal gegoogelt und folgendes gefunden.
ContextMenü mit ListView verbinden und Daten übergeben. - Tutorials & FAQs - Android-Developers
Es scheint also eine Lösung für mein Problem zu geben. Allerdings verstehe ich an dieser Lösung einiges nicht, ohne es zu verstehen will ich es nicht implementieren.

Was bewirkt startManagingCursor z.B.,

Desweiteren ist mir mit einem simpleCursorAdapter nicht geholfen. Ich müsste das ganze auf meinen Code anpassen.

Kann jemand von euch den gesamten Code nachvollziehen?


er nutzt halt einen CursorAdapter, das musst ja nicht. für dich interessant ist eher folgendes

info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();

info.position

und schon hast die ausgewählte listen position. dann nur noch vom adapter das objekt holen und schon hast alles was du brauchst ( je nachdem was dein adapter für daten hält )

ist ja jetzt echt nicht so ne große herausforderung oder ?
 
  • Danke
Reaktionen: Micka
@samarek das gewählte Menuitem zu finden ist kein Problem aber die Id des Datenbankeintrags der dahinter steckt ist knifflig.

@swordi greift info.position auf die Methode GetItemId des ListAdapters zu oder woher kennt AdapterView.AdapterContextMenuInfo die id des Eintrags in der Datenbank?

Oder gibt info.position mir die id des TextViews das geklickt wurde?
 
info.position ist, wie der name schon sagt, die position in der liste

position = 3 wird das dritte element sein.

einfach getItem(position) aufrufen und du bekommst das item aus dem adapter. logisch oder?
 
  • Danke
Reaktionen: Micka
Gut. Aber die position in der Array List des Adapters stimmt nicht immer mit drr id in der Datenbank überein. Werde am Sonntag wieder an der App arbeiten und dann berichten.
 
tja wie auch schon öfters hier geschrieben.

du gibst doch dem adapter deine daten, dann gib ihm ein objekt, welches auch die datenbank id enthält.

mit getItem(pos) holst dir das objekt und liest die db id.

ein wenig eigeninitiative
 
  • Danke
Reaktionen: Micka
Genau so hab ich es mir gedacht swordi. Aber irgendwie scheint es nicht zu klappen. Wenn ich getItem(info.position) aufrufe wird eine ArrayIndexOutOfBoundException geschmissen.

Ich poste hier mal meinen Adapter, meine Activity und den LogCatOutput.
Durch Unterstreichung und Fettdruck hervorgehoben:
- Zeilenangaben im LogCat
- Betreffende Zeile in der Activity
- Betreffende Zeile im ListAdapter

Meine Activity: (EintraegeAnzeigenActivity.java)
Code:
package micka.haushaltsbuch;

import java.util.ArrayList;
import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RadioGroup;
import android.widget.SimpleCursorAdapter;
import android.widget.Spinner;

public class EintraegeAnzeigenActivity extends ListActivity
{
    final static String MY_DB_NAME = "FinanzenDB";
    static String MY_DB_TABLE = "eintraege";
    private static final int COLUMN_INDEX_TITLE = 1; //Titel des Contextmenüs
    SQLiteDatabase myDB;
    final static String tag="ensacom"; 
    private EintragListAdapter mAdapter;
    private ArrayList<Eintrag> mData = new ArrayList<Eintrag>();
    
        
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        
        initiateData();
        final Bundle extras = getIntent().getExtras();
        if(extras != null)
        {
            MY_DB_TABLE = extras.getString(StartHaushaltsbuchActivity.TABELLENNAME);
        }
        mAdapter = new EintragListAdapter(this, mData);
        View header = getLayoutInflater().inflate(R.layout.eintraegetitellayout, null);
        ListView listView = getListView();
        registerForContextMenu(listView);
        listView.addHeaderView(header);
        this.setListAdapter(mAdapter);
    }
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
                                    ContextMenuInfo menuInfo) {
      super.onCreateContextMenu(menu, v, menuInfo);
      MenuInflater inflater = getMenuInflater();
      inflater.inflate(R.menu.eintragcontext, menu);
    }
    @Override
    public boolean onContextItemSelected(MenuItem item) {
      AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
      long id;
      switch (item.getItemId()) {
      case R.id.eintrag_context_bearbeiten:
          [U][B]id = mAdapter.getItemId(info.position);[/B] [B]//Zeile 69[/B][/U]
          eintragLoeschen(id);
          finish();
          return true;
      case R.id.eintrag_context_loeschen:
          return true;
      default:
        return super.onContextItemSelected(item);
      }
    }
    private void eintragLoeschen(long id)
    {
        final Bundle extras = getIntent().getExtras();
        if(extras != null)
        {
            MY_DB_TABLE = extras.getString(StartHaushaltsbuchActivity.TABELLENNAME);
        }
        myDB = null;
        myDB = this.openOrCreateDatabase(MY_DB_NAME, MODE_PRIVATE, null);
        try
        {    
            System.out.println(id);
            myDB.execSQL("DELETE FROM " + MY_DB_TABLE+ " WHERE _id=" + id + ";");
        }catch(SQLException esql)
        {
            System.out.println(esql.toString());
        }
        myDB.close();
    }
    public void eintragBearbeiten(View v)
    {
        
    }
    private void initiateData()
    {
        myDB = null;
        final Bundle extras = getIntent().getExtras();
        if(extras != null)
        {
            MY_DB_TABLE = extras.getString(StartHaushaltsbuchActivity.TABELLENNAME);
        }
        Eintrag eintrag;
        myDB = this.openOrCreateDatabase(MY_DB_NAME, MODE_PRIVATE, null);
        
            Cursor eintragCursor = myDB.rawQuery("SELECT _id, day, month, year, wofuer, betrag FROM " + MY_DB_TABLE + " Order By day, month, year", null);
            
            eintragCursor.moveToFirst();            
            
            
            if(eintragCursor.moveToFirst())
            {
                do
                {
                    eintrag = null;
                    eintrag = new Eintrag(eintragCursor.getInt(0),eintragCursor.getInt(1),eintragCursor.getInt(2),eintragCursor.getInt(3),eintragCursor.getString(4),eintragCursor.getDouble(5));
                    mData.add(eintrag);
                        
                    eintragCursor.moveToNext();
                }while(eintragCursor.isAfterLast() == false);
            }
            eintragCursor.close();
            myDB.close();
    }
}
Mein ListAdapter: (EintragListAdapter.java)
Code:
package micka.haushaltsbuch;

import java.util.ArrayList;

import android.app.ListActivity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class EintragListAdapter extends BaseAdapter
{
    private ArrayList<Eintrag> mData = new ArrayList<Eintrag>();
    
    private final LayoutInflater mLayoutInflater;

    public EintragListAdapter(Context pContext, ArrayList<Eintrag> pData)
    {
                    mData = pData;
                    mLayoutInflater = (LayoutInflater) pContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
    public int getCount() 
    {
        return mData.size();
    }
    public Object getItem(int pPosition) 
    {
        return mData.get(pPosition);
    }
    public long getItemId(int pPosition) 
    {
        [U][B]Eintrag eintrag = mData.get(pPosition); //Zeile 38[/B][/U]
        return eintrag._id;
    }
    public void changeData(ArrayList<Eintrag> pData)
    {
        mData = pData;
        this.notifyDataSetChanged();
    }
    
    public View getView(int pPosition, View convertView, ViewGroup parent) 
    {
        if (convertView == null) 
        {
            convertView = mLayoutInflater.inflate(R.layout.eintraegeanzeigenlayout, null);
        }
        String datum;
        String day = String.valueOf(((Eintrag)getItem(pPosition)).day);
        String month = String.valueOf(((Eintrag)getItem(pPosition)).month);
        String year = String.valueOf(((Eintrag)getItem(pPosition)).year);
        datum = day + "." + month + "." + year;
        ((TextView) convertView.findViewById(R.id.eintraegeAnzeigenDatum)).setText(datum);
        ((TextView) convertView.findViewById(R.id.eintraegeAnzeigenDatum)).setId(((Eintrag)getItem(pPosition))._id);
        ((TextView) convertView.findViewById(R.id.eintraegeAnzeigenZweck)).setText(((Eintrag)getItem(pPosition)).wofuer);
        ((TextView) convertView.findViewById(R.id.eintraegeAnzeigenZweck)).setId(((Eintrag)getItem(pPosition))._id);
        String betrag = String.valueOf(((Eintrag)getItem(pPosition)).betrag);
        ((TextView) convertView.findViewById(R.id.eintraegeAnzeigenBetrag)).setText(betrag);
        ((TextView) convertView.findViewById(R.id.eintraegeAnzeigenBetrag)).setId(((Eintrag)getItem(pPosition))._id);;
        
        return convertView;
    }
    
}
LogCat:
Code:
01-15 14:08:45.453: W/KeyCharacterMap(320): No keyboard for id 0
01-15 14:08:45.453: W/KeyCharacterMap(320): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
01-15 14:08:52.532: D/dalvikvm(320): GC_FOR_MALLOC freed 6183 objects / 311624 bytes in 75ms
01-15 14:08:52.602: V/ensacom(320): Insert new Eintrag: 1.1.2011, 1, 1.0
01-15 14:09:10.703: D/AndroidRuntime(320): Shutting down VM
01-15 14:09:10.703: W/dalvikvm(320): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
01-15 14:09:10.733: E/AndroidRuntime(320): FATAL EXCEPTION: main
[U][B]01-15 14:09:10.733: E/AndroidRuntime(320): java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
[/B][B]01-15 14:09:10.733: E/AndroidRuntime(320):     at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257)[/B][/U]
01-15 14:09:10.733: E/AndroidRuntime(320):     at java.util.ArrayList.get(ArrayList.java:311)
[U][B]01-15 14:09:10.733: E/AndroidRuntime(320):     at micka.haushaltsbuch.EintragListAdapter.getItemId(EintragListAdapter.java:38)[/B][/U]
[U][B]01-15 14:09:10.733: E/AndroidRuntime(320):     at micka.haushaltsbuch.EintraegeAnzeigenActivity.onContextItemSelected(EintraegeAnzeigenActivity.java:69)
[/B][/U]01-15 14:09:10.733: E/AndroidRuntime(320):     at android.app.Activity.onMenuItemSelected(Activity.java:2199)
01-15 14:09:10.733: E/AndroidRuntime(320):     at com.android.internal.policy.impl.PhoneWindow$ContextMenuCallback.onMenuItemSelected(PhoneWindow.java:2744)
01-15 14:09:10.733: E/AndroidRuntime(320):     at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:143)
01-15 14:09:10.733: E/AndroidRuntime(320):     at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:855)
01-15 14:09:10.733: E/AndroidRuntime(320):     at com.android.internal.view.menu.MenuDialogHelper.onClick(MenuDialogHelper.java:137)
01-15 14:09:10.733: E/AndroidRuntime(320):     at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:874)
01-15 14:09:10.733: E/AndroidRuntime(320):     at android.widget.AdapterView.performItemClick(AdapterView.java:284)
01-15 14:09:10.733: E/AndroidRuntime(320):     at android.widget.ListView.performItemClick(ListView.java:3382)
01-15 14:09:10.733: E/AndroidRuntime(320):     at android.widget.AbsListView$PerformClick.run(AbsListView.java:1696)
01-15 14:09:10.733: E/AndroidRuntime(320):     at android.os.Handler.handleCallback(Handler.java:587)
01-15 14:09:10.733: E/AndroidRuntime(320):     at android.os.Handler.dispatchMessage(Handler.java:92)
01-15 14:09:10.733: E/AndroidRuntime(320):     at android.os.Looper.loop(Looper.java:123)
01-15 14:09:10.733: E/AndroidRuntime(320):     at android.app.ActivityThread.main(ActivityThread.java:4627)
01-15 14:09:10.733: E/AndroidRuntime(320):     at java.lang.reflect.Method.invokeNative(Native Method)
01-15 14:09:10.733: E/AndroidRuntime(320):     at java.lang.reflect.Method.invoke(Method.java:521)
01-15 14:09:10.733: E/AndroidRuntime(320):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
01-15 14:09:10.733: E/AndroidRuntime(320):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
01-15 14:09:10.733: E/AndroidRuntime(320):     at dalvik.system.NativeStart.main(Native Method)
Sieht jemand wo das Problem liegt?
 
Vielleicht ist die Klasse Eintrag auch noch interessant, daher hier noch schnell die Klasse.

Code:
package micka.haushaltsbuch;

public class Eintrag 
{
    int _id;
    int day;
    int month;
    int year;
    String wofuer;
    double betrag;
    
    public Eintrag(int id,int tag, int monat, int jahr, String zweck, double betrag)
    {
        this._id = id;
        this.day = tag;
        this.month = monat;
        this.year = jahr;
        this.wofuer = zweck;
        this.betrag = betrag;
    }
    public Eintrag()
    {
        
    }
}
 
So, nach einer Mütze schlaf habe ich nun etwas anderes probiert und siehe da, es klappt. Mein Problem ist also Offiziell gelöst.

Code:
public boolean onContextItemSelected(MenuItem item) 
    {
      AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
      switch (item.getItemId()) {
      case R.id.eintrag_context_bearbeiten:
           [B]eintragBearbeiten(info.id);[/B]
          finish();
          return true;
      case R.id.eintrag_context_loeschen:
          eintragLoeschen(info.id);
          finish();
          return true;
      default:
        return super.onContextItemSelected(item);
      }
    }
Warum wieso weshalb der voherige Versuch über die Position das Objekt zu kriegen nicht geklappt hat würde mich jedoch dennoch interessieren, eilt aber nicht.

Danke nochmal an alle, die ein Teil ihrer Zeit investiert haben um mir zu helfen.
 

Ähnliche Themen

D
Antworten
17
Aufrufe
405
datNeMo
D
M
Antworten
3
Aufrufe
161
moin
M
Y
Antworten
4
Aufrufe
1.220
swa00
swa00
Zurück
Oben Unten