S.M_Emamian S.M_Emamian - 3 months ago 19
Android Question

Custom cursoradapter wrong position

when I click call_btn button, it shows wrong position !

like this picture is my listview :

(The red numbers are wrong)

enter image description here

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


I've seen these quastions before:

Wrong position in Custom Adapter

custom cursor adapter wrong position

Answer

A Cursor is just a result set from the database with a position pointer into the current row. As you scroll your list and new rows are filled in based on your cursor data, this position pointer is automatically moved for you under the covers.

So when bindView() is called for each row in your list, the position is set correctly, which is why your TextViews have the correct text, but when the call_btn.onClick() is called, we don't know what the cursor's current position is, and there is definitely no guarantee that it's pointing to the same position that it was when onClickListener was instantiated when bindView() was called.

The solution is pretty simple. Try replacing your bindView() method with this edited version below, which explicitly saves the position and then uses that to move the cursor to the right row in the onClick() method:

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

       }}); 


 }
Comments