Cheskandroid
Cheskandroid

Reputation: 69

Switch changes ON-OFF when scrolled in Listview Android

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.

Upvotes: 4

Views: 1705

Answers (3)

HelpinCodingpls
HelpinCodingpls

Reputation: 79

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;
}

Upvotes: 4

Sufian
Sufian

Reputation: 6555

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:

  1. 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);
        }
    });
    
  2. replace holder.switchItem.setOnCheckedChangeListener(switchItemOnCheckedChangeListener); with:

    //restore switch state
    holder.switchItem.setChecked(listView.isItemChecked(position));
    
  3. 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);

Upvotes: 0

Arun Shankar
Arun Shankar

Reputation: 2295

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

Upvotes: 0

Related Questions