ListViewAdapter extends CursorAdapter 滚动时顺序混乱
ListViewAdapter extends CursorAdapter order messes up when scrolled
我很困惑。我在网上找到了一些建议,但我无法在此代码上实现它。这是我的问题。每次我滚动时,列表视图的顺序都会混乱。我不知道该怎么做。我真的需要一些帮助。我会非常感谢你的好意。这是我的代码:
public class ListViewAdapterMeasurement extends CursorAdapter {
TextView lblContent, lblDate;
DBHelper dbHelper;
Button btnSelect;
public ListViewAdapterMeasurement(Context context, Cursor c) {
super(context, c, FLAG_REGISTER_CONTENT_OBSERVER);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = LayoutInflater.from(context).inflate(R.layout.details_feed, parent, false);
lblContent = (TextView) view.findViewById(R.id.lblContent);
lblDate = (TextView) view.findViewById(R.id.lblDate);
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
View convertView = view;
if (convertView == null)
{
LayoutInflater vi = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(R.layout.details_feed, null);
}
dbHelper = new DBHelper(getApplicationContext());
int intContentIndex = cursor.getColumnIndex((Tables.FeedTable.COLUMN_CONTENT));
String strContentIndex = cursor.getString(intContentIndex);
int intDateIndex = cursor.getColumnIndex((Tables.FeedTable.COLUMN_DATE));
String strDateIndex = cursor.getString(intDateIndex);
lblContent.setText(strContentIndex);
lblDate.setText(strDateIndex);
}
}
在 Android 中,视图可以多次使用,这意味着 "newView" 中已经实例化的视图可以在 "bindView" 中使用,而不是 once.To 清楚: "newView" 的调用频率 (<=) 低于 "bindView"。因此,在 "newView" 中保存状态不是您可以做的事情。在 "newView" 中,您只能操作对从此适配器实例化的所有视图计数的属性,这些视图在 "bindView" 中未被操作。每个单行(或项目)的所有动态值都已在 "bindView" 中设置,因为可以(并且将)出现重复使用的视图。在您的适配器中保存行(或项目)的单个内部视图会导致意外行为并且无法完成。这是你的问题。 "newView" 在 "view-object-pool" 中没有已实例化且空闲(未显示/可回收)的视图时调用。此外,您还必须考虑重置 "bindView" 中的某些子视图,以防此处出现已填充的视图,并且在特殊情况下 属性 对于某些 row/item 保持未设置状态。最后:你无法知道在 "bindView" 中给定的视图是新建的还是回收的。希望清楚的东西。快乐编码
您的代码的主要问题是 lblContent
和 lblDate
是适配器的成员,并且在调用 newView()
时会被覆盖。相反,您应该为在 newView()
中实例化的每个 View
存储一对这些变量,并在 bindView()
.
中使用它们
为了达到这个目的,可以使用所谓的ViewHolder pattern。可以在下面的代码中看到这种模式背后的一般思想(这是基于你的原始代码,但我没有测试它):
public class ListViewAdapterMeasurement extends CursorAdapter {
/**
* One instance of this class will be attached to each View in order to prevent
* repeated calls to findViewById()
*/
private static class ViewHolder {
private TextView lblContent;
private TextView lblDate;
public ViewHolder(TextView content, TextView date) {
lblContent = content;
lblDate = date;
}
}
DBHelper dbHelper;
public ListViewAdapterMeasurement(Context context, Cursor c) {
super(context, c, FLAG_REGISTER_CONTENT_OBSERVER);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = LayoutInflater.from(context).inflate(R.layout.details_feed, parent, false);
TextView lblContent = (TextView) view.findViewById(R.id.lblContent);
TextView lblDate = (TextView) view.findViewById(R.id.lblDate);
ViewHolder viewHolder = new ViewHolder(lblContent, lblDate); // put references to sub-Views into ViewHolder
view.setTag(viewHolder); // attach ViewHolder to each newly created View
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
dbHelper = new DBHelper(getApplicationContext());
int intContentIndex = cursor.getColumnIndex((Tables.FeedTable.COLUMN_CONTENT));
String strContentIndex = cursor.getString(intContentIndex);
int intDateIndex = cursor.getColumnIndex((Tables.FeedTable.COLUMN_DATE));
String strDateIndex = cursor.getString(intDateIndex);
ViewHolder viewHolder = (ViewHolder) view.getTag(); // retrieve View's ViewHolder
viewHolder.lblContent.setText(strContentIndex);
viewHolder.lblDate.setText(strDateIndex);
}
}
我很困惑。我在网上找到了一些建议,但我无法在此代码上实现它。这是我的问题。每次我滚动时,列表视图的顺序都会混乱。我不知道该怎么做。我真的需要一些帮助。我会非常感谢你的好意。这是我的代码:
public class ListViewAdapterMeasurement extends CursorAdapter {
TextView lblContent, lblDate;
DBHelper dbHelper;
Button btnSelect;
public ListViewAdapterMeasurement(Context context, Cursor c) {
super(context, c, FLAG_REGISTER_CONTENT_OBSERVER);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = LayoutInflater.from(context).inflate(R.layout.details_feed, parent, false);
lblContent = (TextView) view.findViewById(R.id.lblContent);
lblDate = (TextView) view.findViewById(R.id.lblDate);
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
View convertView = view;
if (convertView == null)
{
LayoutInflater vi = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(R.layout.details_feed, null);
}
dbHelper = new DBHelper(getApplicationContext());
int intContentIndex = cursor.getColumnIndex((Tables.FeedTable.COLUMN_CONTENT));
String strContentIndex = cursor.getString(intContentIndex);
int intDateIndex = cursor.getColumnIndex((Tables.FeedTable.COLUMN_DATE));
String strDateIndex = cursor.getString(intDateIndex);
lblContent.setText(strContentIndex);
lblDate.setText(strDateIndex);
}
}
在 Android 中,视图可以多次使用,这意味着 "newView" 中已经实例化的视图可以在 "bindView" 中使用,而不是 once.To 清楚: "newView" 的调用频率 (<=) 低于 "bindView"。因此,在 "newView" 中保存状态不是您可以做的事情。在 "newView" 中,您只能操作对从此适配器实例化的所有视图计数的属性,这些视图在 "bindView" 中未被操作。每个单行(或项目)的所有动态值都已在 "bindView" 中设置,因为可以(并且将)出现重复使用的视图。在您的适配器中保存行(或项目)的单个内部视图会导致意外行为并且无法完成。这是你的问题。 "newView" 在 "view-object-pool" 中没有已实例化且空闲(未显示/可回收)的视图时调用。此外,您还必须考虑重置 "bindView" 中的某些子视图,以防此处出现已填充的视图,并且在特殊情况下 属性 对于某些 row/item 保持未设置状态。最后:你无法知道在 "bindView" 中给定的视图是新建的还是回收的。希望清楚的东西。快乐编码
您的代码的主要问题是 lblContent
和 lblDate
是适配器的成员,并且在调用 newView()
时会被覆盖。相反,您应该为在 newView()
中实例化的每个 View
存储一对这些变量,并在 bindView()
.
为了达到这个目的,可以使用所谓的ViewHolder pattern。可以在下面的代码中看到这种模式背后的一般思想(这是基于你的原始代码,但我没有测试它):
public class ListViewAdapterMeasurement extends CursorAdapter {
/**
* One instance of this class will be attached to each View in order to prevent
* repeated calls to findViewById()
*/
private static class ViewHolder {
private TextView lblContent;
private TextView lblDate;
public ViewHolder(TextView content, TextView date) {
lblContent = content;
lblDate = date;
}
}
DBHelper dbHelper;
public ListViewAdapterMeasurement(Context context, Cursor c) {
super(context, c, FLAG_REGISTER_CONTENT_OBSERVER);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = LayoutInflater.from(context).inflate(R.layout.details_feed, parent, false);
TextView lblContent = (TextView) view.findViewById(R.id.lblContent);
TextView lblDate = (TextView) view.findViewById(R.id.lblDate);
ViewHolder viewHolder = new ViewHolder(lblContent, lblDate); // put references to sub-Views into ViewHolder
view.setTag(viewHolder); // attach ViewHolder to each newly created View
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
dbHelper = new DBHelper(getApplicationContext());
int intContentIndex = cursor.getColumnIndex((Tables.FeedTable.COLUMN_CONTENT));
String strContentIndex = cursor.getString(intContentIndex);
int intDateIndex = cursor.getColumnIndex((Tables.FeedTable.COLUMN_DATE));
String strDateIndex = cursor.getString(intDateIndex);
ViewHolder viewHolder = (ViewHolder) view.getTag(); // retrieve View's ViewHolder
viewHolder.lblContent.setText(strContentIndex);
viewHolder.lblDate.setText(strDateIndex);
}
}