Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select multiple items from listview and change color of selected item only

I want to make a view where I can select multiple items from listview and also side by side am changing the color of selected list item and saving that item into my arraylist..My list is shown as below as:

enter image description here

But when I used to scroll it.. It is showing me 1 more item selected, even I am not selecting it like:

enter image description here

But I want that only that list item color should change where I will click...

I am using the code as:

     private class ItemsAdapter extends ArrayAdapter<String> {
 List<String> items;
  Context context;
  private LayoutInflater inflater;
  public ItemsAdapter(Context context, List<String> part_array_list) {
     super( context, R.layout.part_list, R.id.label,part_array_list );

     inflater = LayoutInflater.from(context) ;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
      TextView textView ; 
    String item = (String) this.getItem( position ); 

      if ( convertView == null ) {
        convertView = inflater.inflate(R.layout.part_list, null);

        // Find the child views.
        textView = (TextView) convertView.findViewById( R.id.label );


        // Optimization: Tag the row with it's child views, so we don't have to 
        // call findViewById() later when we reuse the row.
        convertView.setTag( new ListViewHolder(textView) );


      }
      // Reuse existing row view
      else {
        // Because we use a ViewHolder, we avoid having to call findViewById().
        ListViewHolder viewHolder = (ListViewHolder) convertView.getTag();

        textView = viewHolder.getTextView() ;

      }


      textView.setText( part_array_list.get(position) );      

      return convertView;


      }
      }
        /** Holds child views for one row. */
           private class ListViewHolder {

 private TextView textView ;
 public ListViewHolder() {}
 public ListViewHolder( TextView textView ) {

   this.textView = textView ;
 }

 public TextView getTextView() {
   return textView;
 }
 public void setTextView(TextView textView) {
   this.textView = textView;
 }    

}

and in OnCreate() method,

         final ArrayAdapter<String> part_list_adapter=new ItemsAdapter(AssetSearch.this, part_array_list);
        //PartNumber_List.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    PartNumber_List.setAdapter(part_list_adapter);

    PartNumber_List.setOnItemClickListener(new OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View v, int position,
            long id) {
         ListViewHolder viewHolder = (ListViewHolder) v.getTag();
         viewHolder.getTextView().setBackgroundColor(R.color.result_image_border);

        String item=(String) part_list_adapter.getItem((int) id);
        });
like image 759
Kanika Avatar asked Apr 11 '12 05:04

Kanika


4 Answers

The issue here is that you are setting the background color to the view, then when you scroll, you end up reusing that view due to using convertView. This is exactly what you should be doing, so good job there.

But, of course, that means list items are selected when they shouldn't be. In order to fix this, your getView() method needs to reset the background color to its default value. I don't know what the color was originally, but I'll assume it was transparent. So you would put:

textView.setBackgroundColor(android.R.color.transparent);

So now you're setting the background color to its default, but if you scroll away from the selected item, then back to it, it will have a transparent background instead of the selected background. To resolve this, put an ArrayList of Integer values inside your adapter class. When an item is clicked and onItemClick() is triggered, add the item position to that ArrayList. For example, say you have:

public ArrayList<Integer> selectedIds = new ArrayList<Integer>();

in your adapter class. Then, your onItemClick method would look like this:

@Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {

     ArrayList<Integer> selectedIds = ((ItemsAdapter) parent).selectedIds;
     Integer pos = new Integer(position);
     if(selectedIds.contains(pos) {
         selectedIds.remove(pos);
     }
     else {
         selectedIds.add(pos);
     }

     parent.notifyDataChanged();
}

So, finally, in your getView() method, add this line:

textView.setBackground(selectedIds.contains(position) ? R.color.result_image_border : androi.R.color.transparent);  
like image 52
Jason Robinson Avatar answered Oct 26 '22 23:10

Jason Robinson


I have also encountered this problem, and found out that it is because recycling views. If i remember right setting this removes recycling and fixes the problem, but it's not the best option here.

@Override
public int getItemViewType(int position) {
    return IGNORE_ITEM_VIEW_TYPE;
}
like image 22
Niko Avatar answered Oct 26 '22 23:10

Niko


Keep track of the items selected in the listView in the Activity. In the getView of the adapter check if position equals selected position in the listview and setBackgroundColor for the view there. This will work.

like image 29
user936414 Avatar answered Oct 27 '22 00:10

user936414


Whatever you try to do with ConvertView in itemClick listener it will reflect in some other class, to avoid that you need to set the background for corresponding view holder , i show up some sample which works fine for me,

public View getView(final int position, View convertView, ViewGroup parent) {
         System.gc();
         final ViewHolder holder;

         if (convertView == null) {
             convertView = mInflater.inflate(R.layout.albumlist, null);
             holder = new ViewHolder();
             holder.albumName = (TextView) convertView.findViewById(R.id.albumDetails);

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


         holder.albumName.setText(albumData[position][0]);

         holder.albumName.setOnClickListener(new View.OnClickListener() {
             public void onClick(View v) {
                 holder.albumName.setBackgroundColor(R.color.black);


             }});

         return convertView;
 }

     class ViewHolder {

         TextView albumName;


     }

sample o/p enter image description here

like image 45
Karthi Avatar answered Oct 27 '22 00:10

Karthi