newView 和 bindView 的 CursorAdapter 不一致
CursorAdapter inconsistent between newView and bindView
我对 Android CursorAdapter 中的 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 中的问题相同,但我没有找到任何解决问题的建议。
感谢您对这种奇怪行为的任何解释或问题的解决方案!
默认情况下,ListView
(以及任何其他采用 CursorAdapter
的来源会尝试尽可能多地重用视图。
因此 newView()
仅在创建足够的视图之前被调用,之后,只有 bindView()
在您向下滚动列表时被调用,因为它会重用已创建的视图。
如果您有多个视图类型(就像您看起来的那样),您还应该覆盖 getViewTypeCount() and 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;
}
}
默认情况下,游标适配器仅采用一种行布局并根据行类型重用视图,这就是为什么您在左侧看到子项的原因。
有两种选择:使用一个视图并在绑定时适当地隐藏注释,或者研究重写方法
getItemViewType(int position)
和
getViewTypeCount()
我对 Android CursorAdapter 中的 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 中的问题相同,但我没有找到任何解决问题的建议。
感谢您对这种奇怪行为的任何解释或问题的解决方案!
默认情况下,ListView
(以及任何其他采用 CursorAdapter
的来源会尝试尽可能多地重用视图。
因此 newView()
仅在创建足够的视图之前被调用,之后,只有 bindView()
在您向下滚动列表时被调用,因为它会重用已创建的视图。
如果您有多个视图类型(就像您看起来的那样),您还应该覆盖 getViewTypeCount() and 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;
}
}
默认情况下,游标适配器仅采用一种行布局并根据行类型重用视图,这就是为什么您在左侧看到子项的原因。
有两种选择:使用一个视图并在绑定时适当地隐藏注释,或者研究重写方法
getItemViewType(int position)
和
getViewTypeCount()