Reputation: 39
I have a List View that has several rows created by inflator, each row has two TextView and three check boxes. Everything work ok, but when I uses my finger to scroll down or up I noted that some check box goes to checked automatically. I don't know why it does this when using scroll.
my code :
public class InteractiveArrayAdapter extends ArrayAdapter<Student> implements
Filterable {
final String NAMESPACE = "http://ws.sams.com";
String URL = "http://88.198.82.92:8080/sams1/services/InsertDataWS?WSDL"; // usint
// localhost
final String METHOD_NAME = "insertApsentData";
final String SOAP_ACTION = "http://ws.sams.com/insertApsentData";
List<Integer> checkBoxState = new ArrayList<Integer>(200);
// List<Integer> checkBoxState2 = new ArrayList<Integer>(200);
// List<Integer> checkBoxState3 = new ArrayList<Integer>(200);
// Set<Integer> numbers = new HashSet<Integer>();
private final List<Student> StudentNamesList; // for the student names .
private final List<Student> StudentIdsList; // for the student ids .
private final Activity context;
public InteractiveArrayAdapter(Activity context,
List<Student> StudentNamesList, List<Student> StudentIdsList) {
super(context, R.layout.activity_list, StudentNamesList);
this.context = context;
this.StudentNamesList = StudentNamesList;
this.StudentIdsList = StudentIdsList;
}
protected Button sumbit;
class ViewHolder {
protected TextView StudentName;
protected TextView StudentId;
protected CheckBox checkbox;
protected CheckBox checkbox2;
protected CheckBox checkbox3;
protected TableRow row;
}
public View getView(final int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.rep, null);
ViewHolder viewHolder = new ViewHolder();
viewHolder.StudentName = (TextView) view
.findViewById(R.id.TextView07);
viewHolder.StudentId = (TextView) view
.findViewById(R.id.TextView08);
viewHolder.checkbox = (CheckBox) view.findViewById(R.id.CheckBox05);
viewHolder.checkbox2 = (CheckBox) view
.findViewById(R.id.CheckBox02);
viewHolder.checkbox3 = (CheckBox) view
.findViewById(R.id.CheckBox01);
viewHolder.row = (TableRow) view.findViewById(R.id.TableRow05);
// final EditText searchEdit = (EditText)
// view.findViewById(R.id.searchlable);
Typeface font = Typeface.createFromAsset(context.getAssets(),
"extrafine.ttf");
Typeface fontar = Typeface.createFromAsset(context.getAssets(),
"extrafinear.ttf");
viewHolder.StudentName.setTypeface(fontar);
viewHolder.StudentId.setTypeface(font);
sumbit = (Button) context.findViewById(R.id.sumbitbtn);
view.setTag(viewHolder);
viewHolder.row.setTag(StudentNamesList.get(position)); // here note
viewHolder.checkbox.setTag(StudentNamesList.get(position));
viewHolder.checkbox2.setTag(StudentNamesList.get(position));
viewHolder.checkbox3.setTag(StudentNamesList.get(position));
} else {
view = convertView;
((ViewHolder) view.getTag()).checkbox.setTag(StudentNamesList
.get(position));
((ViewHolder) view.getTag()).checkbox2.setTag(StudentNamesList
.get(position));
((ViewHolder) view.getTag()).checkbox3.setTag(StudentNamesList
.get(position));
((ViewHolder) view.getTag()).row.setTag(StudentNamesList
.get(position));
}
final ViewHolder holder = (ViewHolder) view.getTag();
holder.StudentName.setText(StudentNamesList.get(position).getName());
holder.StudentId.setText(StudentIdsList.get(position).getName());
holder.checkbox.setChecked(StudentNamesList.get(position).isSelected());
holder.checkbox2
.setChecked(StudentNamesList.get(position).isSelected());
holder.checkbox3
.setChecked(StudentNamesList.get(position).isSelected());
holder.checkbox
.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (isChecked) {
holder.checkbox2.setChecked(false);
holder.checkbox3.setChecked(false);
holder.row.setBackgroundResource(R.drawable.green);
} else {
}
((Student) holder.checkbox.getTag()).setSelected(true);
if (((CheckBox) holder.checkbox).isChecked()) {
ViewGroup row1 = (ViewGroup) holder.checkbox
.getParent();
View view1 = ((ViewGroup) row1).getChildAt(4);
if (view1 instanceof TextView) {
holder.StudentName = (TextView) view1;
checkBoxState.add(Integer
.parseInt(holder.StudentName.getText()
.toString()));
}
}
}
});
holder.checkbox3
.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (isChecked) {
holder.row.setBackgroundResource(R.drawable.red);
holder.checkbox2.setChecked(false);
holder.checkbox.setChecked(false);
} else {
}
((Student) holder.checkbox3.getTag()).setSelected(true);
// Toast.makeText(context,
// holder.text.getText().toString() ,
// Toast.LENGTH_SHORT).show();
if (((CheckBox) holder.checkbox3).isChecked()) {
ViewGroup row1 = (ViewGroup) holder.checkbox3
.getParent();
// for (int itemPos = 1; itemPos < ((ViewGroup)
// row1).getChildCount(); itemPos++) {
View view1 = ((ViewGroup) row1).getChildAt(4);
if (view1 instanceof TextView) {
holder.StudentName = (TextView) view1;
// numbers.add(Integer.parseInt(holder.StudentName.getText().toString()));}
checkBoxState.add(Integer
.parseInt(holder.StudentName.getText()
.toString()));
}
// else{
// checkBoxState.add(1);}
}
}
});
holder.checkbox2
.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (isChecked) {
holder.row.setBackgroundResource(R.drawable.blue);
holder.checkbox.setChecked(false);
holder.checkbox3.setChecked(false);
} else {
}
((Student) holder.checkbox2.getTag()).setSelected(true);
// Toast.makeText(context,
// holder.text.getText().toString() ,
// Toast.LENGTH_SHORT).show();
if (((CheckBox) holder.checkbox2).isChecked()) {
ViewGroup row1 = (ViewGroup) holder.checkbox2
.getParent();
// for (int itemPos = 1; itemPos < ((ViewGroup)
// row1).getChildCount(); itemPos++) {
View view1 = ((ViewGroup) row1).getChildAt(4);
if (view1 instanceof TextView) {
holder.StudentName = (TextView) view1;
// numbers.add(Integer.parseInt(holder.StudentName.getText().toString()));}
checkBoxState.add(Integer
.parseInt(holder.StudentName.getText()
.toString()));
}
// else{
// checkBoxState.add(1);}
}
}
});
sumbit.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
for (int i = 0; i < checkBoxState.size(); i++) {
Toast.makeText(context, checkBoxState.get(i).toString(),
Toast.LENGTH_SHORT).show();
// For webservice propose
try {
SoapObject request = new SoapObject(NAMESPACE,
METHOD_NAME);
PropertyInfo pi = new PropertyInfo();
pi.setName("SID");
pi.setValue(Integer.parseInt(checkBoxState.get(i)
.toString()));
pi.setType(Integer.class);
SharedPreferences mPrefs = context
.getSharedPreferences("ITeacher", 0);
// int str1 = mPrefs.getInt("1",0);
int str1 = 1;
PropertyInfo pi2 = new PropertyInfo();
pi2.setName("TID");
pi2.setValue(str1);
pi2.setType(Integer.class);
PropertyInfo pi3 = new PropertyInfo();
pi3.setName("class_id");
pi3.setValue(str1);
pi3.setType(Integer.class);
request.addProperty(pi);
request.addProperty(pi2);
request.addProperty(pi3);
final SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
final HttpTransportSE androidHttpTransport = new HttpTransportSE(
URL);
androidHttpTransport.call(SOAP_ACTION, envelope);
}
catch (Exception e) {
}
}
}
});
return view;
}
}
Upvotes: 1
Views: 208
Reputation: 521
If you know the items to be checked or unchecked before starting then just set it to the adapter that you are using like this
if (checkBoxState.contains(categories.get(position).categoryid)) {
holder.checkbox.setChecked(true);
} else {
holder.checkbox.setChecked(false);
}
Then continue the code like this
holder.checkbox
.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (isChecked) {
checkBoxState.add(categories.get(position).categoryid);
} else {
checkBoxState.remove(categories.get(position).categoryid);
}
}
});
Upvotes: 1
Reputation: 1244
ListView
reuses the rows to create new ones (hence the convertView argument in getView). In your code, if you get a convertView that isn't null, you have to change its checkbox checked state to what is relevant for the new content.
Since the rows are being re-drawn, the checked state of checkbox at Row 1, for example, would be copied to the row which was copied from Row 1; thus setting the CheckBox
of the new row to checked.
Working implementation to solve your problem would be to use an array of boolean values to store the current state of each checkbox/es.
boolean[] itemChecked;
And then in getView, you set a listener on checkbox checked (have to make position final for this to work). You also set the checked state using the array.
cb.setOnCheckedChangeListener (new OnCheckedChangeListener () {
public void onCheckedChanged (CompoundButton btn, boolean isChecked) {
itemChecked[position] = isChecked;
}
});
cb.setChecked(itemChecked[position]);
But again, the use of an array would be considered inefficient if you have a huge number of elements in your list.
Upvotes: 0
Reputation: 26547
This is because the views get recycled. When you scroll through the ListView, views which go off screen are reused to avoid inflating them again.
It's up to you to ensure that the checkboxes are updated properly in the getView()
method of your adapter each time it is called. Else they will remain checked if they were checked the last time the view was used.
Upvotes: 0