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" 中给定的视图是新建的还是回收的。希望清楚的东西。快乐编码

您的代码的主要问题是 lblContentlblDate 是适配器的成员,并且在调用 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);
  }

}