List View + Context Menu: Jedes List Item immer ID 3, aber warum???

  • Antworten:9
  • Bentwortet
Wdmprojekt
  • Forum-Beiträge: 33

19.01.2011, 16:59:22 via Website

Hallo,

ich möchte einzelne Items einer Liste löschen, weshalb ich die Liste zunächst mit einem SimpleCursorAdapter binde,
um Daten aus meiner Datenbank auf die List View zu projezieren. Anschließend registriere ich die Liste für das Context Menu.
Nun ist es egal welches Item ich anklicke (ID0, ID1, ID2,... IDn-1, IDn), ich erhalte immer den 3. Listeneintrag.

Meine Frage lautet warum dies so ist und nicht dynamisch?

Das Menu ist in XML definiert und sieht so aus:
1<?xml version="1.0" encoding="utf-8"?>
2<menu xmlns:android="http://schemas.android.com/apk/res/android">
3 <item android:id="@+id/edit"
4 android:title="@string/menu_context_edit" />
5 <item android:id="@+id/terminate"
6 android:title="@string/menu_context_terminate" />
7 <item android:id="@+id/delete"
8 android:title="@string/menu_context_delete" />
9</menu>

Die Klasse mit der Liste ist wie folgt aufgebaut:
1public class VertraegeListe extends Activity {
2 // Constants
3 public static final String TAG = "VertraegeListe";
4 public static final int ACTIVITY_EDIT = 0;
5
6 // Variables
7 private VertraegeDBAdapter mDbHelper;
8 private ListView mAgreementList;
9
10 /** Called when the activity is first created. */
11 @Override
12 public void onCreate(Bundle savedInstanceState) {
13 Log.v(TAG, "Activity State: onCreate()");
14 super.onCreate(savedInstanceState);
15
16 // Initialize mDbHelper
17 mDbHelper = new VertraegeDBAdapter(this);
18 mDbHelper.open();
19
20 // Set layout for this Activity
21 setContentView(R.layout.vertraege_liste);
22
23 // Handling UI objects
24 mAgreementList = (ListView) findViewById(R.id.vertraege_liste);
25
26 // If agreements exist in database project them on list
27 fillData();
28
29 // Register agreement list for context menu (entry 1 => delete, entry 2 => delete, ...)
30 registerForContextMenu(mAgreementList);
31 }
32
33 // The menu, when a user touches a list element for a longer period
34 @Override
35 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
36 super.onCreateContextMenu(menu, v, menuInfo);
37
38 AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo;
39
40 menu.setHeaderTitle("Aktivitäten [ list id "+info.position+"]");
41
42 MenuInflater inflater = getMenuInflater();
43 inflater.inflate(R.menu.menu_context, menu);
44 }
45
46 // The menu, when a user has touched a list element for a longer period
47 @Override
48 public boolean onContextItemSelected(MenuItem item) {
49 AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
50 switch (item.getItemId()) {
51 case R.id.edit:
52 editAgreement(info.id);
53 return true;
54 case R.id.terminate:
55 generateTermination(info.id);
56 return true;
57 case R.id.delete:
58 confirmDeletionOfAgreement(info.id);
59 return true;
60 default:
61 return super.onContextItemSelected(item);
62 }
63 }
64
65 /**
66 * Get agreements from database and project records on list
67 */
68 private void fillData() {
69 // Get all of the rows from the database and create the item list
70 Cursor mAgreementsCursor = mDbHelper.getAllAgreements();
71 startManagingCursor(mAgreementsCursor);
72
73 // Create an array to specify the fields we want to display in the list (only TITLE)
74 String[] from = new String[]{VertraegeDBAdapter.KEY_AGREEMENTNAME};
75
76 // and an array of the fields we want to bind those fields to (in this case just agreementEntryText)
77 int[] to = new int[]{R.id.agreementEntryText};
78
79 // Now create a simple cursor adapter and set it to display
80 SimpleCursorAdapter agreementsAdapter =
81 new SimpleCursorAdapter(this, R.layout.vertraege_datensatz, mAgreementsCursor, from, to);
82 mAgreementList.setAdapter(agreementsAdapter);
83 }
84}

— geändert am 19.01.2011, 17:38:21

Antworten
Ansgar M
  • Forum-Beiträge: 1.544

19.01.2011, 18:20:08 via App

Sorry, hab mich verlesen..

Lg Ansgar

— geändert am 19.01.2011, 18:20:58

Antworten
Wdmprojekt
  • Forum-Beiträge: 33

19.01.2011, 18:24:32 via Website

Zum einen gibt es so eine Methode nicht und zum anderen würde dies keinen Sinn machen:

Diese Zeile dient dazu der Variable info des Objekttyps AdapterContextMenuInfo alle Informationen
aus dem übergebenden Objekt (MenuItem item) zuzuschreiben.

Danke für Deine Mühen, aber das ist nicht der Fehler.

Antworten
Ansgar M
  • Forum-Beiträge: 1.544

19.01.2011, 18:28:17 via App

Ja, wie im geänderten Beitrag zu lesen, war ich in den Zeilen verrutscht.. Die Methode war geraten, als grobe Richtung.
Lg Ansgar

Antworten
Wdmprojekt
  • Forum-Beiträge: 33

19.01.2011, 18:40:02 via Website

Ich finde es auf jeden Fall nett, dass Du Interesse zeigst, vielen Dank dafür ;)

Ich habe mich eigentlich an den Beitrag auf
http://developer.android.com/guide/topics/ui/menus.html#context-menu
gehalten, weswegen es mir komisch vorkommt, dass das Menu nun
zwar erscheint, aber die Listen Elemente nicht richtig zuweist
beziehungsweise immer ein und dieselbe ID besitzt...

— geändert am 19.01.2011, 18:46:21

Ansgar M

Antworten
Gelöschter Account
  • Forum-Beiträge: 294

19.01.2011, 23:29:43 via Website

War ein langer Tag deshalb nur mein erster Eindruck. Hat es einen bestimmten Grund von Activity abzuleiten und nicht von ListActivity.

Gruß
Harald

Antworten
Wdmprojekt
  • Forum-Beiträge: 33

20.01.2011, 12:46:13 via Website

Ob ich nun eine ListView in einer Activity selbst definiere oder von ListView erbe, was macht das für einen Unterschied? :blink:

Spaßeshalber habe ich nun einmal von ListView geerbt, hat aber keinerlei Effekt auf mein Problem:

1public class VertraegeListe extends ListActivity {
2 // Constants
3 public static final String TAG = "VertraegeListe";
4 public static final int ACTIVITY_EDIT = 0;
5
6 // Variables
7 private VertraegeDBAdapter mDbHelper;
8
9 /** Called when the activity is first created. */
10 @Override
11 public void onCreate(Bundle savedInstanceState) {
12 Log.v(TAG, "Activity State: onCreate()");
13 super.onCreate(savedInstanceState);
14
15 // Initialize mDbHelper
16 mDbHelper = new VertraegeDBAdapter(this);
17 mDbHelper.open();
18
19 // Set layout for this Activity
20 setContentView(R.layout.vertraege_liste);
21
22 // If agreements exist in database project them on list
23 fillData();
24
25 // Register agreement list for context menu (entry 1 => delete, entry 2 => delete, ...)
26 registerForContextMenu(getListView());
27 }
28
29 // The menu, when a user touches a list element for a longer period
30 @Override
31 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
32 super.onCreateContextMenu(menu, v, menuInfo);
33
34 AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
35
36 menu.setHeaderTitle("Aktivitäten [ list id "+info.position+"]");
37
38 MenuInflater inflater = getMenuInflater();
39 inflater.inflate(R.menu.menu_context, menu);
40 }
41
42 // The menu, when a user has touched a list element for a longer period
43 @Override
44 public boolean onContextItemSelected(MenuItem item) {
45 AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
46 switch (item.getItemId()) {
47 case R.id.edit:
48 editAgreement(info.id);
49 return true;
50 case R.id.terminate:
51 generateTermination(info.id);
52 return true;
53 case R.id.delete:
54 confirmDeletionOfAgreement(info.id);
55 return true;
56 default:
57 return super.onContextItemSelected(item);
58 }
59 }
60
61 /**
62 * Get agreements from database and project records on list
63 */
64 private void fillData() {
65 // Get all of the rows from the database and create the item list
66 Cursor mAgreementsCursor = mDbHelper.getAllAgreements();
67 startManagingCursor(mAgreementsCursor);
68
69 // Create an array to specify the fields we want to display in the list (only TITLE)
70 String[] from = new String[]{VertraegeDBAdapter.KEY_AGREEMENTNAME};
71
72 // and an array of the fields we want to bind those fields to (in this case just agreementEntryText)
73 int[] to = new int[]{R.id.agreementEntryText};
74
75 // Now create a simple cursor adapter and set it to display
76 SimpleCursorAdapter agreements =
77 new SimpleCursorAdapter(this, R.layout.vertraege_datensatz, mAgreementsCursor, from, to);
78 setListAdapter(agreements);
79 }

— geändert am 20.01.2011, 13:13:53

Antworten
Wdmprojekt
  • Forum-Beiträge: 33

20.01.2011, 16:27:29 via Website

Die Lösung des Problems lag nicht auf Java-Seite, sondern auf der Datenbank-Seite.

Bei drei Tabellen, die mit Joins kommunizieren, darf wohl nur eine Tabelle das Attribut "_ID"
besitzen (welches notwendig ist für startManagingCursor()) .

Nach dieser Berücksichtigung wurde aus

Tabelle1{_id,...,n}
Tabelle2{_id,...,m}
Tabelle3{_id,...,p}

nun

Tabelle1{_id,...,n}
Tabelle2{_idBezeichner2,...,m}
Tabelle3{_idBezeichner3,...,p}

Antworten
Gelöschter Account
  • Forum-Beiträge: 294

20.01.2011, 21:47:22 via Website

Ob ich nun eine ListView in einer Activity selbst definiere oder von ListView erbe, was macht das für einen Unterschied

Die ListActivity kommt gegenüber der Activity mit ein paar netten eingebauten Handlern und Methoden die einem das Leben erleichtern - wenn man denn mag. Ich denke da nur zum Beispiel an onListItemClick. Aber es geht natürlich wie immer auch anders. Ich persönlich versuche immer den bequemsten Weg zu wählen - den mit den besten Features für die jeweilige Anforderung.

Harald

— geändert am 20.01.2011, 21:47:41

Antworten
Gelöschter Account
  • Forum-Beiträge: 294

20.01.2011, 21:53:37 via Website

Tabelle1{_id,...,n}
Tabelle2{_idBezeichner2,...,m}
Tabelle3{_idBezeichner3,...,p}

Würde ich nicht machen. Du kannst mit "as" eine Spalte in einem Join umbenennen kannst aber gleichzeitig beim Select auf einzelne Tabellen alles beim Alten belassen. Beispiel:

1select _id, ... from tabelle1
2select _id, ... from tabelle2
3
4select tab1._id, tab2._id as wasauchimmer from tabelle1 tab1 inner join tabelle2 tab2 on ...

— geändert am 20.01.2011, 21:54:19

Antworten