Skip to content Skip to sidebar Skip to footer

Custom Listview Multiselection

I am developing Listview where Multiple selection is possible,now the problem is when i scroll down or up the selection of items get lost and selection made on any other item excep

Solution 1:

http://www.marvinlabs.com/2010/10/custom-listview-ability-check-items/

check this

Edited

holder.chkField.setChecked(true);
holder.chkField.setTag(R.id.chkItem, position);
check.add(position, true);   

You need to change this as

if(check.getAt(position)){ 
   holder.chkField.setChecked(true);
}else{
   holder.chkField.setChecked(false);
}
holder.chkField.setTag(R.id.chkItem, position);

Put below line in Check listener on checked condition put true or false

check.add(position, isChecked);          

Solution 2:

public class ListAdapter extends BaseAdapter{

private LayoutInflater mInflater;
private ArrayList<String> arrPublicData;    
privateint checkCount = 0;
private ArrayList<Boolean> check = new ArrayList<Boolean>();

 publicListAdapter(Context context,ArrayList<String> arrPublicData) {

    this.mInflater = LayoutInflater.from(context);
    this.arrPublicData = arrPublicData;
    checkCount = arrPublicData == null ? 0 : arrPublicData.size();
}

publicintgetCount() {
    return arrPublicData.size();
}

public Object getItem(int position) {
    return position;
}

publiclonggetItemId(int position) {
    return position;
}

public View getView(int position, View convertView, ViewGroup parent) {
    final ViewHolder holder;
    View rowView = convertView;

    if (rowView == null) {
        rowView = mInflater.inflate(R.layout.multiselect_row, null);
        holder = new ViewHolder();

        holder.txtField = (TextView) rowView.findViewById(R.id.txtItem);
        holder.chkField = (CheckBox) rowView.findViewById(R.id.chkItem);
        holder.chkField.setOnCheckedChangeListener(checkedChangeListener);
        holder.chkField.setChecked(true);
        holder.chkField.setTag(R.id.chkItem, position);
        check.add(position, true);      
        rowView.setTag(holder);

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

    holder.txtField.setText(arrPublicData.get(position));    
    if(check.get(position) == true)
    {
       holder.chkField.setText(arrPublicData.get(position));    
    }
    else
    {
       holder.chkField.setText(arrPublicData.get(position));    
    }       

    return rowView;
}

class ViewHolder { TextView txtField; CheckBox chkField; }

I think you are not checking condition whether checkbox is checked or not so your checkbox get change when you scroll your listview hope that will help

Solution 3:

Problem is in your getView method, please correct this as follows:

publicclassContactPickerActivityextendsActivity {

    private ArrayList<Contacts> arr = newArrayList<Contacts>();
    private Context context;
    private ListView list;
    private ContactArrayAdapter adapter;
    private String strName,strNumber;
    private View view;  
    publicstaticboolean[] arrBoolean = null;

    @OverridepublicvoidonCreate(Bundle savedInstance) {
        super.onCreate(savedInstance);
        //setContentView(R.layout.contact_picker);ProgressDialogpd=newProgressDialog(this);
        list = (ListView)findViewById(R.id.contactList);
        arr = newArrayList<Contact>();
        context = ContactPickerActivity.this;
        arr =  displayContacts();
        arrBoolean=newboolean[arr.size()];
        Arrays.fill(arrBoolean, false);
        Log.i("ContactPicker", "Completed Displaying Contact list ::: " + arr.size());
        adapter = newContactArrayAdapter(this,arr);
        list.setAdapter(adapter);
//              list.setAdapter(new ArrayAdapter<String>(this,//                      android.R.layout.simple_list_item_multiple_choice, listContent));
        list.setOnItemClickListener(ContactSelectedListener);
        Log.i("Boolaean >>> ", arrBoolean.size() + "");


    }

    privateOnItemClickListenerContactSelectedListener=newOnItemClickListener() {
        @OverridepublicvoidonItemClick(AdapterView<?> parent, View arg1, int position,long arg3) {
            Log.i("ListViewTest","Item Click");
            arrBoolean[position]=!arrBoolean[position];
            adapter.notifyDataSetChanged();
        }
    };

    private ArrayList<Contacts> displayContacts() {

        ContentResolvercr= getContentResolver();
        Cursorcur= cr.query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
        Contacts contact;
        if (cur.getCount() > 0) {
            while (cur.moveToNext()) {
                contact = newContacts();
                Stringid= cur.getString(cur.getColumnIndex(People._ID));
                Stringname= cur.getString(cur.getColumnIndex(People.DISPLAY_NAME));
                contact.setName(name);
                arr.add(contact);
            }
        }
        return arr;
    }
}
//********* Adapter *****publicclassContactArrayAdapterextendsBaseAdapter {

//  private final List<Contact> list;private Context context;    

    private LayoutInflater mInflater;
    private List<Contacts> list; 

     publicContactArrayAdapter(Context context,ArrayList<Contact> arrPublicData) {

        this.mInflater = LayoutInflater.from(context);
        this.list = arrPublicData;
    }

    publicintgetCount() {
        return list.size();
    }

    public Object getItem(int position) {
        return position;
    }

    publiclonggetItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        Viewview= convertView;
        final ViewHolder viewHolder;
        if (view == null) {         
            view = mInflater.inflate(R.layout.multiselect_row, null);
            viewHolder = newViewHolder();
            viewHolder.text = (TextView) view.findViewById(R.id.txtItem);
            viewHolder.checkbox = (CheckBox) view.findViewById(R.id.chkItem);


            view.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) view.getTag();
        }
        ViewHolderholder= (ViewHolder) view.getTag();
        holder.text.setText(list.get(position).getName());
        holder.checkbox.setChecked(ContactPickerActivity.arrBoolean[position]);        
        return view;
    }

    staticclassViewHolder {
    protected TextView text;
    protected CheckBox checkbox;
}

Solution 4:

Its happening because you have inflated a checkBox with same id multiple times. So modify your code in following way,

  1. Add a TableRow/LinearLayout in Xml in the place of checkBox.

  2. in the getView method create a CheckBox at run time and set its ID as the position (list position) and add it to the TableRow/LinearLayout in xml using addView() method.

  3. now if the problem still persists, In CheckChanged Listener create Vector and add the position of checked items in the vector and while creating checkBox have a check on the Vector if the current view position is checked then use setChecked(true) method to check it.

may be i'm not clear but i don't know a better way to explain it.

Solution 5:

I have created a sample program, in which I am setting background color of the view according to state of the row, just change changing backgrouund code to check state;

publicclassSampleActivityextendsActivity {
    private String[] arrItems={"A", "B", "C", "D", "E"};
    privateboolean[] arrState={false, false, false, false, false};
    private ListView lv;
    private ArrAdapter adapter;
    /** Called when the activity is first created. */@OverridepublicvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        lv=(ListView) findViewById(R.id.lvTest);
        adapter=newArrAdapter(this);
        lv.setAdapter(adapter);
        lv.setOnItemClickListener(newOnItemClickListener() {

            @OverridepublicvoidonItemClick(AdapterView<?> adapterView, View view, int position,
                    long id) {
                // TODO Auto-generated method stub
                arrState[position]=!arrState[position];
                adapter.notifyDataSetChanged();
            }
        });

    }

    privateclassArrAdapterextendsArrayAdapter<String>
    {
        Context mContext=null;
        publicArrAdapter(Context context) {
            super(context, R.layout.row);
            // TODO Auto-generated constructor stub
            mContext=context;
        }

        @OverridepublicintgetCount() {
            // TODO Auto-generated method stubreturn arrItems.length;
        }

        @Overridepublic View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            View vi=convertView;
            ViewHolder holder=null;
            if(vi==null)
            {
                vi=LayoutInflater.from(mContext).inflate(R.layout.row, parent, false);
                holder=newViewHolder();
                holder.mTxt=(TextView) vi.findViewById(R.id.text1);
                vi.setTag(holder);
            }
            else
                holder=(ViewHolder) vi.getTag();
            holder.mTxt.setText(arrItems[position]);
            if(arrState[position])
                vi.setBackgroundColor(Color.BLUE);
            else
                vi.setBackgroundColor(Color.WHITE);
            returnsuper.getView(position, convertView, parent);
        }


        privateclassViewHolder
        {
            TextView mTxt=null;
        }


    }

    privatevoidclear()
    {
        Arrays.fill(arrState, false);
        adapter.notifyDataSetChanged();
    }
}

Post a Comment for "Custom Listview Multiselection"