| |||||||
Das Thema "Custom SimpleCursorAdapter - Sections Problem" befindet sich unter Android App Entwicklung auf Android-Hilfe.de.
|
| | Themen-Optionen | Ansicht |
| | #1 (permalink) | |
| Erfahrener Benutzer Modell: Galaxy S i9100 Registriert seit: 14.05.2010
Beiträge: 278
Abgegebene Danke: 9
Erhielt 5 Danke für 5 Beiträge
| Ich versuche gerade in meiner ListView Sections einzublenden. Beispiel: Zitat:
In einer LinkedHashMap<Integer, String> speichere ich mit <Position (Cursor Position), Sectionname> die Sections. Diese Funktion funktioniert soweit sehr gut. In getView() rufe ich die Methode getItemViewType() auf, um zu entscheiden, ob die aktuelle Cursor Position ein normaler Eintrag oder eine Section ist. Das Ganze klappt auch soweit ganz gut - es werden Sections und normale Einträge angezeigt. Mein Problem ist nun, dass die Einträge, die normalerweise auf der Section Position wären, verschwinden bzw. nicht angezeigt werden. Hier meine Custom SimpleCursorAdapter Klasse: Code: public class NewsAdapter_new extends SimpleCursorAdapter {
protected static final String TAG = "NewsAdapter";
protected static final int TYPE_HEADER = 0x00;
protected static final int TYPE_NORMAL = 0x01;
protected static final int TYPE_COUNT = 0x02;
protected final LayoutInflater mInflater;
protected final LinkedHashMap<Integer, String> mSections;
protected int mCurrentSectionMapSize = 0;
public NewsAdapter_new(Context context, int layout, Cursor c,
String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
mInflater = LayoutInflater.from(mContext);
mSections = getSeparators();
mCursor.moveToFirst();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int viewType = getItemViewType(position);
mCursor.moveToPosition(position);
switch (viewType) {
case TYPE_NORMAL: {
// Normale Einträge werden hier initialisiert
break;
}
case TYPE_HEADER: {
// Header-View wird hier initialisiert
break;
}
}
return convertView;
}
@Override
public int getCount() {
if (mCursor.getCount() != 0) {
return super.getCount() + mSections.keySet().size();
}
return 0;
}
@Override
public int getItemViewType(int position) {
if (mSections == null) {
return TYPE_NORMAL;
} else {
if (mSections.containsKey(position)) {
return TYPE_HEADER;
} else {
return TYPE_NORMAL;
}
}
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
if (mSections == null) {
return true;
}
return !mSections.containsKey(position);
}
@Override
public int getViewTypeCount() {
return TYPE_COUNT;
}
protected LinkedHashMap<Integer, String> getSeparators() {
LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();
String newDate = "";
String oldDate = "";
mCursor.moveToFirst();
if (!mCursor.isAfterLast()) {
do {
String currentString = mCursor.getString(mCursor.getColumnIndex(ArticleCol.DATE));
newDate = currentString.substring(0, 10);
if (!newDate.contentEquals(oldDate)) {
map.put(mCursor.getPosition(), Util.formatBackToRealDate(newDate));
}
oldDate = newDate;
} while (mCursor.moveToNext());
}
return map;
}
} Vielen Dank, Grüße Metti | |
| | |
| | #2 (permalink) |
| Erfahrener Benutzer Modell: G1 DevPhone / SGS2 / SGT10.1v Registriert seit: 20.01.2009
Beiträge: 238
Abgegebene Danke: 7
Erhielt 50 Danke für 47 Beiträge
|
Du musst deine "Header" aus der position von "getView" rausrechnen. Im Konkreten: getView(0) -> Header 0 getView(1) -> getItem(1-1 = 0) getView(2) -> getItem(2-1 = 1); getView(3) -> getItem(3-1 = 2); getView(4) -> getItem(4-1 = 3); getView(5) -> Header 1 getView(6) -> getItem(6-2 = 4); etc. (für dein Beispiel) |
| | |
| | #4 (permalink) |
| Erfahrener Benutzer Modell: G1 DevPhone / SGS2 / SGT10.1v Registriert seit: 20.01.2009
Beiträge: 238
Abgegebene Danke: 7
Erhielt 50 Danke für 47 Beiträge
|
Nein - getView wird automatisch aufgerufen. Es kommen quasi für jede position (von 0 bis anzahlElemente die du per getCount() zurückgibst) Anfragen. DU musst nur in dem getView schauen, dass du für jede position den richtigen View zurückgibst. Und dazu gehört halt der richtige Typ (was du schon tust), aber auch das richtige Element aus deinen Listen (das meinte ich mit der getView(x) -> ... zuweisung da oben )
|
| | |
| | #5 (permalink) |
| Erfahrener Benutzer Modell: Galaxy S i9100 Registriert seit: 14.05.2010
Beiträge: 278
Abgegebene Danke: 9
Erhielt 5 Danke für 5 Beiträge
|
In deinem Beispiel sollte also die Berechnung der korrekten Positionen in getItem() stattfinden. Nun habe ich mal ein bisschen debuggt und mir ist aufgefallen, dass der Adapter gar nicht in die getItem() Funktion springt?!
|
| | |
| | #6 (permalink) |
| Erfahrener Benutzer Modell: G1 DevPhone / SGS2 / SGT10.1v Registriert seit: 20.01.2009
Beiträge: 238
Abgegebene Danke: 7
Erhielt 50 Danke für 47 Beiträge
|
Tut er auch nicht von alleine, du musst es wenn dann explizit aufrufen. GetItem() musst du wenn dann explizit aufrufen. MUSST du aber NICHT! Du musst einfach nur sicherstellen, dass für jede Position der richtige Typ zurückgegeben wird (das was du mit der SWITCH-Anweisung machst!) UND je nach Typ das Richtige Element aus einer deiner Liste... Also - wenn getView(0, convertView, parent) aufgerufen wird: gehst du in deinem Switch in "case TYPE_HEADER:" und gibst den View, passend zu deinem ersten Header aus == deineHeader[0] getView(1, convertView, parent) aufgerufen wird: gehst du in deinem Switch in "case TYPE_NORMAL:" und gibst den View, passend zu deinem ersten Element aus deinen Elementen == deineElemente[0] == deineElemente(position-1) getView(2, convertView, parent) aufgerufen wird: gehst du in deinem Switch in "case TYPE_NORMAL:" und gibst den View, passend zu deinem zweitem Element aus deinen Elementen == deineElemente[1] == deineElemente(position-1) ... getView(5, convertView, parent) aufgerufen wird: gehst du in deinem Switch in "case TYPE_HEADER:" und gibst den View, passend zu deinem zweiten Header aus == deineHeader[1] getView(6, convertView, parent) aufgerufen wird: gehst du in deinem Switch in "case TYPE_NORMAL:" und gibst den View, passend zu deinem FÜNFTEN Ersten aus deinen Elementen == deineElemente[5] genau HIER ist die Variable position NICHTMEHR gleich dem X. Element aus deineElemente, sondern deineElemente(position-2) An dieser Stelle ist es dann nichtmehr das SECHSTE Element, sondern eben das FÜNFTE, weil der View zur position FÜNF ein header ist, und genau dein Problem ja ist, dass du jeweils die Elemente aus deinen Elementen nicht angezeigt kriegst, wo ein header ist... Die Beispiele sind kein Copy&Paste-Code sondern sollen dir dein Problem aufzeigen ;-) Debugg doch deine Variante einfach mal durch, dann siehst du das getView() mit den Werten Position 0 bis xx aufgerufen wird - und du aber NIE auf die "normalen Elemente" zugreifst, für die Positionen, wo ein Header angezeigt wird. Geändert von sixi (04.09.2011 um 13:45 Uhr) |
| | |
| Folgender Benutzer bedankt sich bei sixi für diesen Beitrag: | MetBo (04.09.2011) |
| | #7 (permalink) | |
| Erfahrener Benutzer Modell: Galaxy S i9100 Registriert seit: 14.05.2010
Beiträge: 278
Abgegebene Danke: 9
Erhielt 5 Danke für 5 Beiträge
|
Ich habe das Prinzip jetzt verstanden. Ich habe jetzt auch folgendes verändert bzw. eingebunden: Zitat:
| |
| | |
![]() |
|
| Themen-Optionen | |
| Ansicht | |
| |
| ||||
| Thema | Autor | Forum | Antworten | Letzter Beitrag |
| Hilfe ListView <-> SimpleCursorAdapter | Straightflush | Android App Entwicklung | 1 | 07.05.2011 01:12 |
| Spinner mit simplecursoradapter | Gingerbread | Android App Entwicklung | 3 | 03.03.2011 15:34 |
| problem mit custom recovery und custom roms | shiraldi | Root / Hacking / Modding für HTC Desire | 1 | 15.02.2011 00:57 |
| ListView und SimpleCursorAdapter | jaipur | Android App Entwicklung | 2 | 03.04.2010 16:21 |
| Problem Elemente eines SimpleCursorAdapter zu löschen | loriot | Android App Entwicklung | 2 | 12.07.2009 11:42 |