-1

Well i have a listview populated with BaseAdapter. In listview i have 2 textviews and 2 buttons that i want to be clickable and i did set it class and works fine but problem is when i click one textview, 4th, 8th list item below is clicked too and i just find out that they have same position by printing position with toast.

Position on Toast

How can i make that positions go ++ and every of them be uniqe?

Adapter Class

  public class CustomListAdapter extends BaseAdapter  
 {

private ArrayList<FeedItem> listData;
private LayoutInflater layoutInflater;
private Context mContext;

protected ListView feedListView;


public CustomListAdapter(Context context, ArrayList<FeedItem> listData)
{
    this.listData = listData;
    layoutInflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    mContext = context;

}




public void addItem(final FeedItem item) {
    listData.add(item);
    notifyDataSetChanged();
}

@Override
public int getCount()
{
    return listData.size();
}

@Override
public Object getItem(int position)
{
    return listData.get(position);
}

@Override
public long getItemId(int position)
{
    return position;
}


public View getView( final int position, View convertView, ViewGroup parent)
{
 final ViewHolder holder;
 View row=convertView;
    if (row == null)
    {
     convertView = layoutInflater.inflate(R.layout.list_row_layout, null);
     holder = new ViewHolder();
     holder.headlineView = (TextView)convertView.findViewById(R.id.name);
     holder.reportedDateView = (TextView) convertView.findViewById(R.id.confid);
     holder.approve = (TextView) convertView.findViewById(R.id.approveTV);
     convertView.setTag(holder);
    }
    else
    {
        holder = (ViewHolder) convertView.getTag();

    }
    FeedItem newsItem = (FeedItem) listData.get(position);
    holder.approve.setFocusable(true);
    holder.approve.setClickable(true);
    holder.headlineView.setText(Html.fromHtml(newsItem.getTitle()));
    holder.reportedDateView.setText(Html.fromHtml(newsItem.getContent()));



    holder.approve.setTag(position); 
    holder.approve.setOnClickListener(new OnClickListener() {           
      @Override
      public void onClick(View v) 
      {

        Toast.makeText(mContext, String.valueOf(v.getTag()), Toast.LENGTH_LONG).show();
      holder.approve.setTag(v);
      holder.approve.setText("Approved");



      }    
   });

    return convertView;
}

static class ViewHolder
{

    TextView approve;
    TextView headlineView;
    TextView reportedDateView;
    ImageView imageView;
    FeedItem newsItem;

}

}

3 Answers3

1

Listview recycles views.

How ListView's recycling mechanism works

Change getView

public View getView( final int position, View convertView, ViewGroup parent)
{
 ViewHolder holder;
    if (convertView == null)
    {
     convertView = layoutInflater.inflate(R.layout.list_row_layout, null);
     holder = new ViewHolder();
     holder.headlineView = (TextView)convertView.findViewById(R.id.name);
     holder.reportedDateView = (TextView) convertView.findViewById(R.id.confid);
     holder.approve = (TextView) convertView.findViewById(R.id.approveTV);
     convertView.setTag(holder);
    }
    else
    {
        holder = (ViewHolder) convertView.getTag();

    }
    FeedItem newsItem = (FeedItem) listData.get(position);
    holder.approve.setFocusable(true);
    holder.approve.setClickable(true);
    holder.headlineView.setText(Html.fromHtml(newsItem.getTitle()));
    holder.reportedDateView.setText(Html.fromHtml(newsItem.getContent()));
    holder.approve.setTag(position); 
    holder.approve.setOnClickListener(new OnClickListener() {           
      @Override
      public void onClick(View v) 
      {
        Toast.makeText(mContext, String.valueOf(v.getTag()), Toast.LENGTH_LONG).show();
      }    
   });

    return convertView;
}
Community
  • 1
  • 1
Raghunandan
  • 132,755
  • 26
  • 225
  • 256
  • Its working now, before i thank you one question more, i am trying to do when holder.approve is clicked to change text from "approve" to "approved" but same error 4th and 8th listview items got changed text too. Do you know what causes this? – Sandra Mladenovic Dec 08 '13 at 19:38
  • use setTag and gettag as suggested in my post. – Raghunandan Dec 08 '13 at 19:39
  • I have tried that earlier and now again, not working, still other got changed :( I mean on setTag(position) – Sandra Mladenovic Dec 08 '13 at 19:41
  • holder.approve.setTag(position); i tried that in Activity class to solve too but no success – Sandra Mladenovic Dec 08 '13 at 19:44
  • @SandraMladenovic post the code Activity has nothing to do with this. use `TextView b =(TextView) v; b.setText("Hello");` in `onClick` – Raghunandan Dec 08 '13 at 19:45
  • No i tried from Adapter class, but i tried too in Activity, i wasn't sure. I copied your code, but still the same – Sandra Mladenovic Dec 08 '13 at 19:48
  • @SandraMladenovic commenting is not enough post your code by editing your question. post the updated code – Raghunandan Dec 08 '13 at 19:48
  • @SandraMladenovic it happens bcoz listview recycles views. check the link in my post. so when you scroll also changes is not persisted. – Raghunandan Dec 08 '13 at 19:52
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/42757/discussion-between-raghunandan-and-sandra-mladenovic) – Raghunandan Dec 08 '13 at 20:32
1

As you are reusing the view by

else{
        holder = (ViewHolder) convertView.getTag();
    }

so multiple textView using same listener. So Take your onclickListener outside of the if condition.

if (convertView == null)
    {
     convertView = layoutInflater.inflate(R.layout.list_row_layout, null);
     holder = new ViewHolder();
     holder.headlineView = (TextView)convertView.findViewById(R.id.name);
     holder.reportedDateView = (TextView) convertView.findViewById(R.id.confid);
     holder.approve = (TextView) convertView.findViewById(R.id.approveTV);
     convertView.setTag(holder);
    }
    else
    {
        holder = (ViewHolder) convertView.getTag();

    }

    holder.approve.setOnClickListener(new OnClickListener() {           

         @Override
        public void onClick(View v) 
         {
         Toast.makeText(mContext, String.valueOf(position), Toast.LENGTH_LONG).show();
          }    
        });
Md. Monsur Hossain Tonmoy
  • 11,045
  • 2
  • 22
  • 19
0

Add this code in your list adapter :

    @Override
public int getViewTypeCount() {
    // TODO Auto-generated method stub
    return questionsClassArrayList_.size();
}

@Override
public int getItemViewType(int position) {
    // TODO Auto-generated method stub
    return position;
}
Osama Ibrahim
  • 995
  • 10
  • 13