我有一个这样的数据库表:
ID
NAME
COUNTRY_NAME
我想要一个这样的列表:
+ Italy
- Potato
- Tomato
+ France
- Fromage
- Baguette
我写了一个CursorAdapter,每次调用requery时,读取表中的所有项目并将其映射到用于映射每个项目(真实项目或标题)位置的对象。
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上。
该方法有效,但它真的很贵:它需要详细说明整个表格并且我有很多记录。 我正在寻找的是一种简单的方法来映射realPosition - &gt;在滚动ListView的同时使用fakePosition,但我认为的方法太复杂了,我认为如果getView不是线性的(快速滚动?)会破坏它们。
解: 1)COUNTRY_NAME的查询排序。向下滚动real_cursor_position =(请求的位置 - “国家/地区更改#(?)”)。如果在real_position中翻译的请求位置位于具有不同country_name的项目之后,则它是标题。当我向下滚动拳头时,它会破坏,我认为,除非有棘手的解决方案。 ... 没有更多
还有其他解决方案吗?
编辑:另一个问题是我无法预测adapter.getCount()返回的视图数量而不扫描整个表格。
答案 0 :(得分:6)
我编写了简单适配器的getView
方法,向您展示如何构建ListView
,其中包含对具有相同国家/地区的项目进行分组的标题。这将假设标题视图位于每行的布局中,显示/隐藏它作为当前行的需求。使用getItemViewType
方法可以完成同样的事情,并且可以在绑定适配器的各个部分方面做更多的工作。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(
R.layout.rowlayout, parent, false);
}
// for simplicity, the header it's just a TextView
TextView header = (TextView) convertView
.findViewById(R.id.headerPart);
// also for simplicity, the row content it's just a TextView
TextView rowText = (TextView) convertView
.findViewById(R.id.normalPart);
// set the data for the row
mCursor.moveToPosition(position);
rowText.setText(mCursor.getString(mCursor.getColumnIndex("name")));
// this is not the first position
if (position - 1 >= 0) {
// if there is a previous position see if it has the same
// country(in which case you already had set the header)
String currentCountry = mCursor.getString(mCursor
.getColumnIndex("country"));
mCursor.moveToPosition(position - 1);
String previousCountry = mCursor.getString(mCursor
.getColumnIndex("country"));
if (currentCountry.equalsIgnoreCase(previousCountry)) {
// the countries are the same so abort everything as we
// already set the header on one of previous rows
header.setVisibility(View.GONE);
} else {
// this is the first occurrence of this country so show the
// header
header.setVisibility(View.VISIBLE);
header.setText(currentCountry);
}
} else {
// this is position 0 and we need a header here
header.setVisibility(View.VISIBLE);
header.setText(mCursor.getString(mCursor
.getColumnIndex("country")));
}
return convertView;
}