Android Listview With Checkboxes Not Behaving As Expected
Solution 1:
I believe your problem lies in your if/else statement.
If convertView is null then you create a new view and populate it with all the correct data but if it is not null (i.e it is a recycled view), you simply return the exact same view back from the tag. You do not do anything with the view regarding setting its properties so it maintains the state it already had (some of which were checked)
Set your properties after you have a valid viewHolder.
You currently have this model.
if (convertView == null) {
//Your code to create the view// Your code to set the view properties
}else {
holder = (ViewHolder) convertView.getTag();
}
Change it to this (move the code that sets the view properties outside the if/else so that the view properties can be set for all views regardless of whether they are recycled.
if (convertView == null) {
LayoutInflatervi= (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.find_your_location_row, null);
holder = newViewHolder();
holder.LocationImage = (SmartImageView) convertView.findViewById(R.id.loca_row_image);
holder.locationName = (TextView) convertView.findViewById(R.id.txt_loca_name);
holder.LocationDescription = (TextView) convertView.findViewById(R.id.txt_loca_desc);
holder.locationCheckText = (TextView) convertView.findViewById(R.id.txt_check);
holder.locationCheck = (CheckBox) convertView.findViewById(R.id.location_check);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Locationslocation= data.get(position);
holder.LocationImage.setImageUrl(location.getImagePath());
holder.locationName.setText(location.getLocationName());
holder.LocationDescription.setText(location.getLocationDescription());
booleanShouldBoxBeChecked=//Insert check for the current box here
holder.locationCheck.setChecked(ShouldBoxBeChecked);
Solution 2:
You have to do something like this at start make an array list and store state as false
private ArrayList<Boolean> itemChecked = new ArrayList<Boolean>();
for (int i = 0; i < this.getCount(); i++) {
itemChecked.add(i, false); // initializes all items value with false
}
and whenever you click just change the state and populate the list with updated values everytime.
Solution 3:
OnClickListener() is being declared only for the first couple of list items, and is using the same "position" for all the rest of the items.
One option that can work is that you can set the position in the tag of each checkbox in the list and get it in your OnClickListener from the v param
Solution 4:
locationPreferences = context.getSharedPreferences("locationPrefs", context.MODE_PRIVATE);
locationPrefsEditor = locationPreferences.edit();
String locationID = locationPreferences.getString("locationID", "");
try {
if(locationID.contains(String.valueOf(data.get(position).getLocationID()))){
holder.locationCheck.setChecked(true);
}
} catch (Exception e) {
Log.e("Fatal", " Exception");
}
This part of code is only executed, if your convertView == null
. You are not doing setChecked when your convertView != null
, that means when you reuse view, it will not be checked correctly
Solution 5:
Here , i have a solution for you.
Basically i have created two array list of type string. When you check a checkbox, the corresponding textview value ( or whatever value you can store correspoding to that listview item) is stored in it the list CHECKEDLIST. In the other list ALLVALUES, all the values are stored.
On button click i match both the lists and if a match occurs, then i remove that value from ALLVALUES and call notifydatasetchanged
package com.example.test;
import java.io.File;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.CompoundButton.OnCheckedChangeListener;
publicclassMainActivityextendsActivityimplementsOnClickListener {
private ArrayList<String> checkedIndices = newArrayList<String>();
ArrayList<String> list = newArrayList<String>();
AScustomadapter adapter;
intcount=0;
private String[] vidNames = {"a","b","c","d","e","f","g","h","i"};
private ListView myList;
@OverridepublicvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Buttonb1= (Button) findViewById(R.id.button1);
b1.setOnClickListener(this);
for (inti=0; i < vidNames.length; i++) {
list.add(vidNames[i]);
}
myList = (ListView)findViewById(R.id.list);
adapter = newAScustomadapter(getApplicationContext(), list);
myList.setAdapter(adapter);
}
@OverridepublicvoidonClick(View v) {
if(v.getId() == R.id.button1) {
for (inti=0; i < checkedIndices.size(); i++) {
for(intj=0; j <list.size();j++){
if(list.get(j).contains(checkedIndices.get(i))){
list.remove(j);
}
}
}
adapter.notifyDataSetChanged();
}
}
publicclassAScustomadapterextendsBaseAdapter {
private ArrayList<String> mListItems;
private LayoutInflater mLayoutInflater;
inti=0;
publicAScustomadapter(Context context, ArrayList<String> arrayList) {
mListItems = arrayList;
//get the layout inflater
mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@OverridepublicintgetCount() {
return mListItems.size();
}
@Overridepublic Object getItem(int i) {
return list.get(i);
}
@OverridepubliclonggetItemId(int i) {
return0;
}
publicintgetTotalCheckedCount() {
return checkedIndices.size();
}
@Overridepublic View getView(finalint position, View view, ViewGroup viewGroup) {
ViewHolder holder;
if (view == null) {
holder = newViewHolder();
view = mLayoutInflater.inflate(R.layout.list_item, null);
holder.itemName = (TextView) view.findViewById(R.id.list_item_text_view);
holder.cb1 = (CheckBox) view.findViewById(R.id.checkBox1);
view.setTag(holder);
} else {
holder = (ViewHolder)view.getTag();
}
finalStringstringItem= mListItems.get(position);
if (stringItem != null) {
if (holder.itemName != null) {
holder.itemName.setText(stringItem);
}
}
holder.cb1.setOnClickListener(newOnClickListener() {
@OverridepublicvoidonClick(View v) {
//is chkIos checked?if (((CheckBox) v).isChecked()) {
if(!checkedIndices.contains(getItem(index).toString()))
checkedIndices.add(getItem(index).toString()); }
else {
checkedIndices.remove(getItem(index).toString());
}
//case 2
}
});
if(checkedIndices.contains((Integer)position)) {
holder.cb1.setChecked(true);
} else {
holder.cb1.setChecked(false);
}
//this method must return the view corresponding to the data at the specified position.return view;
}
privateclassViewHolder {
protected TextView itemName;
protected CheckBox cb1;
}
}
}
Post a Comment for "Android Listview With Checkboxes Not Behaving As Expected"