次のような db テーブルが 1 つあります。
ID
NAME
COUNTRY_NAME
そして、私はこのようなリストが欲しい:
+ Italy
- Potato
- Tomato
+ France
- Fromage
- Baguette
そして、再クエリが呼び出されるたびに、テーブル上のすべてのアイテムを読み取り、すべてのアイテム (実際のアイテムまたはヘッダー) の位置をマップするために使用されるオブジェクトにマップする CursorAdapter を作成しました。
private static class PersonEntry {
boolean isHeader;
String countryName;
int realPos;
int id;
}
コードはこれです:
/* cursor generated by querying whole table */
public void readHeaders(Cursor cursor ) {
Log.d(this.getClass().getSimpleName(),"readHeaders init");
items = new ArrayList<PersonEntry >();
this.mCursor = cursor;
cursor.moveToFirst();
int i = 0;
String previousCountry = "";
String currentCountry;
while(cursor.isAfterLast() == false) {
int id = cursor.getInt(cursor.getColumnIndexOrThrow(Match.ROW_ID));
currentCountry = cursor.getString(cursor.getColumnIndexOrThrow(Person.ROW_COUNTRY_NAME));
if (!currentCountry.equals(previousCountry)) {
// ho incontrato una nuova nazione
// rispetto alla precedente, aggiungiamola
items.add(new PersonEntry(... define isHeader=true ..));
}
// stiamo comunque scorrendo gli elementi, aggiungiamo quello appena trovato
items.add(new PersonEntry( ... defile isHeader = false ....);
previousCountry = currentCountry;
i++;
cursor.moveToNext();
}
cursor.close();
Log.d(this.getClass().getSimpleName(),"readHeaders end");
}
そこで、getView、bindView、および newView を書き直して、正しいレイアウトを拡張し、realPos-position Cursor に基づいてビューをバインドしました。
メソッドは機能しますが、非常に高価です。テーブル全体を詳しく説明する必要があり、多くのレコードを取得しています。私が探しているのは、ListView のスクロール中に realPosition -> fakePosition をマップする単純な方法ですが、私が考えた方法は複雑すぎて、getView が線形でない場合 (高速スクロール?) は壊れると思います。
解決策: 1) COUNTRY_NAME によるクエリの並べ替え。real_cursor_position = (要求された位置 - "country changes # (?)") を下にスクロールしている間。real_position で変換された要求された位置が別の国名の項目の後にある場合、それはヘッダーです。トリッキーな解決策がない限り、拳を下にスクロールして上にスクロールすると壊れると思います。... これ以上何もない
他の解決策はありますか?
編集: 別の問題は、テーブル全体をスキャンしないと、 adapter.getCount() によって返されるビューの数を予測できないことです。