ListViewAdapter在滚动时扩展CursorAdapter命令

时间:2016-06-19 14:45:42

标签: java android listview android-cursoradapter

我很困惑。我在网上找到了一些建议但我无法在此代码上实现它。这是我的问题。每次我滚动,列出视图的顺序混乱。我不知道该怎么做。我真的需要一些帮助。我真的很感激你的善意。这是我的代码:

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);


  }
}

2 个答案:

答案 0 :(得分:2)

在Android中,视图可以多次使用,这意味着“newView”中已经实例化的视图可以在“bindView”中多次使用。要清楚:“newView”不经常被调用(< = )比“bindView”。因此,在“newView”中保存状态不是您可以做的事情。在“newView”中,您只能操作对从此适配器实例化的所有视图计数的属性,这些属性不在“bindView”中操作。每个单行(或项目)的所有动态值都在“bindView”中设置,因为可以(并且将会)出现重用的视图。保存适配器中行(或项目)的单个内部视图会导致意外行为,无法完成。这是你的问题。当“view-object-pool”中没有实例化和免费(未显示/可循环)视图时,将调用“newView”。此外,您必须考虑重置“bindView”中的某些子视图,如果已经填充的视图出现在此处,并且在特殊情况下某个行/项的属性保持未设置状态。最后:您无法知道在“bindView”中,给定视图是否是新构建的或已回收的视图。希望清楚的事情。快乐的编码

答案 1 :(得分:2)

代码的主要问题是lblContentlblDate是适配器的成员,并且在调用newView()时都会被覆盖。相反,您应该为View中实例化的每个newView()存储这些变量对,并在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);
  }

}