Jetzt kostenlos registrieren. Mitglieder surfen ohne Werbung auf Android-Hilfe.de!
Zurück   Android-Hilfe.de > Android Developer > Android App Entwicklung

Custom SimpleCursorAdapter - Sections Problem

Das Thema "Custom SimpleCursorAdapter - Sections Problem" befindet sich unter Android App Entwicklung auf Android-Hilfe.de.


Antwort

 

Themen-Optionen Ansicht
Alt 03.09.2011, 15:50   #1 (permalink)
Erfahrener Benutzer
 
Benutzerbild von MetBo

Modell: Galaxy S i9100

Registriert seit: 14.05.2010
Beiträge: 278
Abgegebene Danke: 9
Erhielt 5 Danke für 5 Beiträge
Standard Custom SimpleCursorAdapter - Sections Problem

Hallo,

Ich versuche gerade in meiner ListView Sections einzublenden.

Beispiel:
Zitat:
== Section 03.09.2011 ==
News1 03.09.2011
News2 03.09.2011
News3 03.09.2011
News4 03.09.2011
== Section 02.09.2011 ==
News5 02.09.2011
News6 02.09.2011
News7 02.09.2011
== Section 01.09.2011 ==
News8 01.09.2011
News9 01.09.2011
Um dies zu realisieren, habe ich eine eigene SimpleCursorAdapter Klasse (NewsAdapter_new) angelegt.

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;
    }
}
Hat jemand mein Problem verstanden und könnte mir eventuell helfen eine Lösung zu finden?

Vielen Dank,
Grüße Metti
MetBo ist offline   Mit Zitat antworten
Alt 03.09.2011, 16:02   #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
Standard AW: Custom SimpleCursorAdapter - Sections Problem

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)
__________________
Meine App: Die Cocktail App für Android™ - jetzt im Market (PRO)
sixi ist offline   Mit Zitat antworten
Alt 03.09.2011, 17:06   #3 (permalink)
Erfahrener Benutzer
 
Benutzerbild von MetBo

Modell: Galaxy S i9100

Registriert seit: 14.05.2010
Beiträge: 278
Abgegebene Danke: 9
Erhielt 5 Danke für 5 Beiträge
Standard AW: Custom SimpleCursorAdapter - Sections Problem

Also muss ich für jeden Header getView() extra aufrufen?
MetBo ist offline   Mit Zitat antworten
Alt 03.09.2011, 20:19   #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
Standard AW: Custom SimpleCursorAdapter - Sections Problem

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 )
__________________
Meine App: Die Cocktail App für Android™ - jetzt im Market (PRO)
sixi ist offline   Mit Zitat antworten
Alt 04.09.2011, 10:33   #5 (permalink)
Erfahrener Benutzer
 
Benutzerbild von MetBo

Modell: Galaxy S i9100

Registriert seit: 14.05.2010
Beiträge: 278
Abgegebene Danke: 9
Erhielt 5 Danke für 5 Beiträge
Standard AW: Custom SimpleCursorAdapter - Sections Problem

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?!
MetBo ist offline   Mit Zitat antworten
Alt 04.09.2011, 13:42   #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
Standard AW: Custom SimpleCursorAdapter - Sections Problem

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.
__________________
Meine App: Die Cocktail App für Android™ - jetzt im Market (PRO)

Geändert von sixi (04.09.2011 um 13:45 Uhr)
sixi ist offline   Mit Zitat antworten
Folgender Benutzer bedankt sich bei sixi für diesen Beitrag:
MetBo (04.09.2011)
Alt 04.09.2011, 17:57   #7 (permalink)
Erfahrener Benutzer
 
Benutzerbild von MetBo

Modell: Galaxy S i9100

Registriert seit: 14.05.2010
Beiträge: 278
Abgegebene Danke: 9
Erhielt 5 Danke für 5 Beiträge
Standard AW: Custom SimpleCursorAdapter - Sections Problem

Ich habe das Prinzip jetzt verstanden. Ich habe jetzt auch folgendes verändert bzw. eingebunden:

Zitat:
protected LinkedHashMap<Integer, Integer> mTypePosition;
protected LinkedHashMap<Integer, Integer> mOffsetPosition;

@Override
public View getView(int position, View convertView, ViewGroup parent) {
int viewType = getItemViewType(position);

ViewHolder viewHolder = null;
if (convertView == null) {
viewHolder = new ViewHolder();

switch (viewType) {
case TYPE_NORMAL: {
convertView = mInflater.inflate(R.layout.item_article, null);


break;
}
case TYPE_HEADER: {
convertView = mInflater.inflate(R.layout.item_separator, null);

break;
}
}

convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}

switch (viewType) {
case TYPE_NORMAL: {
int pos = position;
for (Entry<Integer, Integer> item : mOffsetPosition.entrySet()) {
if (item.getValue() == position) {
pos = item.getKey();
break;
}
}

mCursor.moveToPosition(pos);

}
case TYPE_HEADER: {

}
}

return convertView;
}

protected LinkedHashMap<Integer, String> getSections() {
LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();
mTypePosition = new LinkedHashMap<Integer, Integer>();
mOffsetPosition = new LinkedHashMap<Integer, Integer>();
String newDate = "";
String oldDate = "";
int position = 0;
int sectionPosition = 0;

mCursor.moveToFirst();

if (!mCursor.isAfterLast()) {
do {
String currentString = mCursor.getString(mCursor.getColumnIndex(ArticleCo l.DATE));
newDate = currentString.substring(0, 10);

if (!newDate.contentEquals(oldDate)) {
map.put(mCursor.getPosition(), Util.formatBackToRealDate(newDate));
sectionPosition++;
mTypePosition.put(position, TYPE_HEADER);
} else {
mTypePosition.put(position, TYPE_NORMAL);
}
mOffsetPosition.put(mCursor.getPosition(), position + sectionPosition);
oldDate = newDate;
position++;
} while (mCursor.moveToNext());
}

return map;
}
Es werden immer noch nicht alle Einträge angezeigt ... ich verzweifel -.-
MetBo ist offline   Mit Zitat antworten
Antwort

Stichworte
-

Themen-Optionen
Ansicht


Ähnliche Themen

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




Du liest gerade: "Custom SimpleCursorAdapter - Sections Problem" unter "Android App Entwicklung" auf Android-Hilfe.de.


Powered by vBulletin®
Copyright ©2000 - 2012, vBulletin Solutions, Inc.
Search Engine Friendly URLs by vBSEO
© Android-Hilfe.de 2012 - All rights reserved.