Bala Sivagnanam Bala Sivagnanam - 6 days ago 5
Android Question

getting item position of the button click inside a listview using cursorAdapter

I am an android newbie.. I am using a cursor adapter and a listview which has a toggle button and a textview... when I click the toggle button I need to get the click event and the position of the item in the list..

I saw many threads but I dont find a perfect solution that works for me...

finally i decided to set the position in bindview and try to retrieve it on click events.. but when I access the holder.position in click event I am getting null pointer exception.

Please help me with this guys. thanks a lot

public class CalendarListAdapter extends CursorAdapter implements OnClickListener{


protected static class RowViewHolder {
public TextView mTitle;
public ToggleButton mButton;
public int position;
}

protected ListView calListView;


@SuppressWarnings("deprecation")
public CalendarListAdapter(Context context, Cursor c) {
super(context, c);
// TODO Auto-generated constructor stub

}


@Override
public void bindView(View view, Context context, Cursor cursor) {
// TODO Auto-generated method stub
TextView title = (TextView) view.findViewById(R.id.calendarName);
System.out.println("cursor details"
+ cursor.getString(cursor.getColumnIndex(cursor
.getColumnName(1))));
title.setText(cursor.getString(cursor.getColumnIndex(cursor
.getColumnName(1))));
Log.d("click position " , "position is " +cursor.getPosition() );
ToggleButton button = (ToggleButton) view.findViewById(R.id.silentToggle);
button.setOnClickListener(this);
Log.d("click position " , "position is " +cursor.getPosition() );
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(context.LAYOUT_INFLATER_SERVICE);

View calendarListView = inflater.inflate(R.layout.calendar_list_item, null);

RowViewHolder rowView = new RowViewHolder();
rowView.mTitle = (TextView)calendarListView.findViewById(R.id.calendarName);
rowView.mButton = (ToggleButton) calendarListView.findViewById(R.id.silentToggle);
rowView.position = cursor.getPosition();

rowView.mTitle.setOnClickListener(titleOnClickListener);
rowView.mButton.setOnClickListener(buttonOnClickListener);

return calendarListView;
}

@Override
public void onClick(View view) {
// TODO Auto-generated method stub

Log.d("item clicked", "clicked" );
RowViewHolder holder = (RowViewHolder)view.getTag();
int position = holder.position;
Log.d("common clicked", "clicked -" +position );


}

private OnClickListener titleOnClickListener = new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
RowViewHolder holder = (RowViewHolder)v.getTag();
int position = holder.position;
Log.d("title clicked", "clicked -" +position );
}
};

private OnClickListener buttonOnClickListener = new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
RowViewHolder holder = (RowViewHolder)v.getTag();
int position = holder.position;
Log.d("button clicked", "clicked -" +position );

}
};

}

Answer

To be able to use v.getTag() you need two things. In newView you need to do

calendarListView.setTag(rowView);

and in bindView you need to insert the correct data into the holder also:

rowView.position = cursor.getPosition(); // (same as in newView)

For all of this to work together, you also need to make sure that the view you are doing getTag() on is the view that you did setTag on.

In your case that would mean doing this in newView:

rowView.mTitle.setTag(rowView);
rowView.mButton.setTag(rowView);

It would probably be simpler to not use RowViewHolder at all. Instead do this:

In bindView:

int pos = cursor.getPosition();
title.setTag(pos);
button.setTag(pos);

And then in your OnClickListeners do

Integer pos = (Integer) v.getTag();

Good luck!

Comments