Question

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

        }
    };

}
Was it helpful?

Solution

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!

OTHER TIPS

the answer above with the setTag and getTag worked well for me, but somehow I realized that the tags not always bring the correct numbers. after checking ,I found out that my newView function works too many times and thats why all my tags are "0" . if you have that problem,check here for solution.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top