Custom Listview Multiselection
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,
Add a TableRow/LinearLayout in Xml in the place of checkBox.
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 usingaddView()
method.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"