我对CursorAdapter中的Android newView和getView如何工作感到困惑。 到目前为止,我见过的大多数实现都实现了getView,但许多在线资源表明这不是可行的方法,例如here。
我的问题归结为以下代码
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// Decide if message was sent by Me or Other
View chatRow;
if(cursor.getInt(cursor.getColumnIndexOrThrow(DbChat.KEY_SENDER_ID)) == 0) {
chatRow = LayoutInflater.from(context.getApplicationContext())
.inflate(R.layout.listrow_chat_me,parent,false);
} else {
chatRow = LayoutInflater.from(context.getApplicationContext())
.inflate(R.layout.listrow_chat_other,parent,false);
}
return chatRow;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
TextView chatText = (TextView) view.findViewById(R.id.chat_text);
ImageView imageView = (ImageView) view.findViewById(R.id.chat_img);
chatText.setText(cursor.getString(cursor.getColumnIndexOrThrow(DbChat.KEY_TEXT)));
if(cursor.getInt(cursor.getColumnIndexOrThrow(DbChat.KEY_SENDER_ID)) == 0) {
imageView.setImageDrawable(ChatActivity.sIconBlue);
} else {
imageView.setImageDrawable(ChatActivity.sIconRed);
}
请注意,newView会设置布局(包括图像的左对齐或右对齐),而bindView会设置图像(在本例中为蓝色或红色)。 因此,预期的行为是左边的所有红色方块和右边的所有蓝色方块(因为颜色和位置都在光标上查询相同的ID检查)。 相反,我得到以下布局:
基本上,我的问题与此question中的问题相同,但我没有找到解决问题的任何建议。
感谢您对此问题的奇怪行为或解决方案的任何解释!
答案 0 :(得分:1)
默认情况下,ListView
(以及CursorAdapter
尝试尽可能多地重复使用视图的任何其他来源。
因此,newView()
仅在创建足够的视图之前被调用,之后,当您重新使用已创建的视图时向下滚动列表时,仅调用bindView()
。
如果您有多种视图类型(就像您所做的那样),您还应该覆盖getViewTypeCount()和getItemViewType()。这些方法告诉适配器只应重用相同类型的视图,以确保使用listrow_chat_me
的行仅用于将来的listrow_chat_me
行,而不会用于listrow_chat_other
行。
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public int getItemViewType(int position) {
// getItem(position) returns a Cursor at the given position
Cursor cursor = (Cursor) getItem(position);
if (cursor.getInt(cursor.getColumnIndexOrThrow(DbChat.KEY_SENDER_ID)) == 0) {
return 0;
} else {
return 1;
}
}
答案 1 :(得分:0)
默认情况下,游标适配器只假设一行布局,并根据行类型重用视图,因此您在左侧看到子项的原因。
有两种选择:使用一个视图,只需在绑定时隐藏备注,或调查覆盖方法
getItemViewType(int position)
和
getViewTypeCount()