自定义CursorAdapter的位置错误

4
当我点击call_btn按钮时,它显示的位置是错误的!
就像这张图片所示,这是我的列表视图:
(红色数字是错误的)
public class MyAdapter extends CursorAdapter
    {
        Context b;

        LayoutInflater inflater;
        @SuppressWarnings("deprecation")
        public MyAdapter(Context context, Cursor c) {
            super(context, c);
            inflater = LayoutInflater.from(context);
            b= (Context) context;
      }

    @Override
    public void bindView(View view, Context context, final Cursor cursor) {
      // TODO Auto-generated method stub
        TextView tv1 = (TextView)view.findViewById(R.id.txt_name);
        TextView tv2 = (TextView)view.findViewById(R.id.txt_numer);

        tv1.setText(cursor.getString(2));
        tv2.setText(cursor.getString(3));


        final Button call_btn= (Button)view.findViewById(R.id.call_btn);    

        call_btn.setOnClickListener(new Button.OnClickListener(){

           @Override
           public void onClick(View v) { 

               Toast.makeText(b, cursor.getString(1), Toast.LENGTH_SHORT).show();

           }}); 


     }

        protected Context getActivity() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
            public View newView(Context context, Cursor cursor, ViewGroup parent) {
            return inflater.inflate(R.layout.item, parent, false);
     }
}

我之前看到过这些问题:

自定义适配器中的错误位置

自定义光标适配器中的错误位置

2个回答

13

Cursor是从数据库返回的一个结果集,其中包含一个指向当前行的指针。当您滚动列表并基于光标数据填充新行时,这个位置指针在幕后自动移动

因此,当为列表中的每一行调用bindView()时,位置将被正确设置,这就是为什么您的TextView具有正确文本的原因,但是当调用call_btn.onClick()时,我们不知道光标的当前位置,而且绝对没有保证它指向bindView()在实例化onClickListener时所指向的同一位置。

解决方案非常简单。尝试使用下面编辑过的版本替换bindView()方法,该方法显式保存位置,然后在onClick()方法中使用它来移动游标到正确的行:

@Override
public void bindView(View view, Context context, final Cursor cursor) {
  // TODO Auto-generated method stub
    TextView tv1 = (TextView)view.findViewById(R.id.txt_name);
    TextView tv2 = (TextView)view.findViewById(R.id.txt_numer);

    tv1.setText(cursor.getString(2));
    tv2.setText(cursor.getString(3));


    final Button call_btn= (Button)view.findViewById(R.id.call_btn);    
    final int position = cursor.getPosition();

    call_btn.setOnClickListener(new Button.OnClickListener(){

       @Override
       public void onClick(View v) { 

           cursor.moveToPosition(position);
           Toast.makeText(b, cursor.getString(1), Toast.LENGTH_SHORT).show();

       }}); 


 }

0
另一个简单的解决方案是将位置保存到按钮标签中,通过setTag(cursor.getPosition())设置到你的call_btn中:
@Override
public void bindView(View view, Context context, final Cursor cursor) {
  // TODO Auto-generated method stub
    TextView tv1 = (TextView)view.findViewById(R.id.txt_name);
    TextView tv2 = (TextView)view.findViewById(R.id.txt_numer);

    tv1.setText(cursor.getString(2));
    tv2.setText(cursor.getString(3));

    final Button call_btn= (Button)view.findViewById(R.id.call_btn);    
    call_btn.setTag(cursor.getPosition());

    call_btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ((MainActivity) context).onBtnClick((int)v.getTag());
        }
    });
}

onClickListener 然后将位置传递给您的活动,在那里您只需声明:

public void onBtnClick(int position) {
    // do your stuff
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接