I have a ListView with a switch. Whenever I turn the switch ON and scroll down and scroll it back up, the switch changes to the turned OFF state.
问题:
回答1:
Put this in your custom adapter..
// THESE TWO METHODS ALLOWS SCROLLABLE WITHOUT SWITCHES BEING TURNED ON/OFF WHEN VIEWS ARE RECYCLED // these methods in fact tell the adapter to not recycle the rows so might slow down process
@Override public int getViewTypeCount() { return getCount(); } @Override public int getItemViewType(int position) { return position; } 回答2:
I have faced this problem with ListViews. Try this
if(checkedItems.indexOf(accountList.get(position).toString()) >= 0) { holder.switchItem.setChecked(true); } else { holder.switchItem.setChecked(false); } You are initializing checkedItems right before you are using it. Its currently empty. How can do a indexOf when there is nothing in it.
This should solve your issue
回答3:
SparseBooleanArray doesn't have any method named indexOf.
If you just want to store checked states, I'd recommend you to use ListView's built in method setItemChecked(int position, boolean value).
In your getView(), you can see if a position is checked (or in your case, your switch's state being ON or OFF) like below:
ListView listView = (ListView)parent; //get the listview listView.setItemChecked(itemPosition, true); //set position as checked listView.isItemChecked(position); //check if position is checked (switch is ON) Make sure you call this on your ListView:
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); Update 1:
In your code:
after
holder.switchItem = (Switch) convertView.findViewById(R.id.switchItem);, add this code:final ListView listView = (ListView)parent; //add listener holder.switchItem.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { listView.setItemChecked(position, isChecked); } });replace
holder.switchItem.setOnCheckedChangeListener(switchItemOnCheckedChangeListener);with://restore switch state holder.switchItem.setChecked(listView.isItemChecked(position));remove the following code:
SparseBooleanArray checkedItems = new SparseBooleanArray(); if (checkedItems.indexOf(accountList.get(position).toString()) >= 0) { holder.switchItem.setChecked(true); }
Update 2:
This my how my adapter looks like:
@Override public int getCount() { return 50; } @Override public String getItem(int position) { return String.valueOf(position); } @Override public View getView(final int position, View convertView, ViewGroup parent) { Holder holder; final ListView listView = (ListView)parent; if(convertView == null || convertView.getTag() == null) { convertView = mInflator.inflate(R.layout.list_item, parent, false); holder = new Holder(); holder.switch1 = (Switch) convertView.findViewById(R.id.switch1); holder.switch1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { listView.setItemChecked(position, isChecked); } }); } else { holder = (Holder) convertView.getTag(); } holder.switch1.setText(getItem(position)); //restore switch state holder.switch1.setChecked(listView.isItemChecked(position)); return convertView; } And this is how I'm setting my listview in my ListActivity:
setListAdapter(new MyAdapter(this)); getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);