androidlistviewcursorandroid-cursoradapter

use click events in cursor adapter


I have a list of items displayed by a cursor adapter, when I use onItemClick, I get the correct row and am able to do what i need (my objective is to add a view to that item on click. now I need this action t happen while clicking a button in the listView cell. however, button click events do not return the correct cell, but rather random other cells in the list, here is an example from my code:

public class CustumAdapter extends CursorAdapter implements OnClickListener{
    
    private Context context;
    
    private Button btn_maybe;

    private String name;

    public CustumAdapter(Context context, Cursor c, LatLng position) {
        super(context, c);
        
        this.position = position;
        this.context = context;
        
    }

    @Override
    public void bindView(View view, final Context context, Cursor c) {
    
        name = c.getString(c.getColumnIndex(ContractPlaces.PLACE_NAME));
        btn_maybe = (Button) view.findViewById(R.id.cursor_layout_maybe);
        btn_maybe.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                
                //i need to use the correct view from BindView here
                
            }
        });
        
        
        
        nameView.setText(name);

In this sample code I want a click on an button in the cell let me accesses the view in which the button really is, however I get back views from random list cells, how can I get the correct cell info in my click listener?

EDIT:

so thanks to @darnmason I figured it out, in order to get a view for a list item using a click event in cursor adapter, set the button in question a tag which will be cursor.getPosition(), so the tag is the correct position of the item, in true essence of the listview life cycle, if I want the View of an item in a specific position I will call

  //where lv is the ListView (you can pass it to the adapter as a parameter).
//getChildAt returns a view in a position
//value is the value of cursor.getPosition() so its the correct position of the item where //the button was clicked.
//lv.getFirstVisiblePosition() is the first position that is actually on screen,
    View view = lv.getChildAt(value - lv.getFirstVisiblePosition());

when you deduct this from the actual position you get the position you need, don't forget to add

 if(view == null)
               return;

to avoid exceptions.


Solution

  • name is declared in the class and overwritten every time bindView is executed, when you click on the button the most recently bound view is shown in the Toast.

    A pattern I like to follow is to store the index of the clickable view in its tag. Then in onClick you get the index from the view, and get the data for that index from the adapter.