0

I think I have searched through all the posts relating to my question but could not find a solution to my problem. I have A ListView with two textviews and one Toggle button. Toggle button Changes its state when I scroll up or down (go out of view). I am using viewholder (suggested on the forum) that does make the button to retain its state but then the recycling property comes into play and mess up my application i.e multiple toggle buttons change their state on one click. What I want? I want my toggle button to retain its previous state when it goes out of view and comes back plus when I click one toggle button only that toggle button should work. Here is my Code for Listview (pardon me for not putting much comments)

    public class ActivityB extends AppCompatActivity {
    ListView list;
    Button edit;
    public String text= "";
    public SharedPreferences.Editor editor;
    public SharedPreferences sharedPreferences;

    private ArrayList<String> data = new ArrayList<String>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_b);
        list = (ListView) findViewById(R.id.listView);
       generateListContent();
        list.setAdapter(new MyListadapter(this,R.layout.constraint,data));
        edit= (Button) findViewById(R.id.button);
        sharedPreferences=getSharedPreferences("MyData",Context.MODE_PRIVATE);
        editor=sharedPreferences.edit();
        text=sharedPreferences.getString("Text","Null");
        //Toast.makeText(this,text,Toast.LENGTH_LONG).show();


    }

   public void generateListContent() {
        for (int i = 0; i < 11; i++) {
            data.add("This is item no " + i);
        }

    }

    private class MyListadapter extends ArrayAdapter<String> {
        private int layout;

        ArrayList<String> list;
        public MyListadapter(@NonNull Context context, @LayoutRes int resource, @NonNull List<String> objects) {
            super(context, resource, objects);
            layout=resource;
            list= (ArrayList<String>) objects;
        }

        @NonNull
        @Override
        public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {
          ViewHolder mainviewHolder=null;
            if(convertView==null){
                LayoutInflater inflater=LayoutInflater.from(getContext());
                convertView= inflater.inflate(layout,parent,false);
                final ViewHolder viewHolder = new ViewHolder();
                viewHolder.title= (TextView) convertView.findViewById(R.id.textView);
            viewHolder.lastone= (TextView) convertView.findViewById(R.id.textView2);
            viewHolder.button= (ToggleButton) convertView.findViewById(R.id.toggleButton);

            //mainviewHolder.title.setText(getItem(position));
                viewHolder.button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                            if (isChecked) {
                                buttonView.setChecked(true);
                                Toast.makeText(getContext(), "Button is On" + position , Toast.LENGTH_LONG).show();
                            } else {
                                buttonView.setChecked(false);
                                Toast.makeText(getContext(), "Button is OFF" + position + buttonView.getId(),Toast.LENGTH_LONG).show();
                            }

                    }
                });

                convertView.setTag(viewHolder);
            }
           else{
               mainviewHolder = (ViewHolder) convertView.getTag();
              mainviewHolder.title.setText(getItem(position));
          }
            return convertView;
        }
    }
    public class ViewHolder{
        TextView title;
        TextView lastone;
        ToggleButton button;
    }

}
  • Yes it happens because of View holder patten. it's like reusing view for next data. What u can do. make a boolean array(size of main array) and save state of the toggle button. u can set it on OnBind view method. – Mohit Kacha May 22 '17 at 11:02

3 Answers3

0

check this...

Recyclerview Changing Items During Scroll

if above does not work....

Method 1

things you can try...

1.check button status outside toggle method....so that every time the listviewe loaded it can assign a value rather no value.

  1. create a method togglebtn(viewHolder) // pass the instance of this perticualr item

  2. Inside togglebtn....modify the toggle btn by reference with the instance.

togglebtn(viewHolder v) { }

Method 2

create a public data structure to hold the status of the button....preferebaly hasmap to store item no+check status....then check this value every time and update.

Feel free to ask.

Community
  • 1
  • 1
0

Instead of creating array list of strings, create a custom object something like below.

Class A {
   public String title;
   public boolean isChecked;
}

Set correct value to isChecked(true/false) depending on toggle button state.

Also add one more line inside getview()

button.setChecked(list.get(position).isChecked)
adarsha nayak v
  • 306
  • 1
  • 9
0

Thanks Everyone for sparing your time and answering my question. With these answers and a little help from forum' other posts, I found a solution. Since I have a limited number of views so i removed the if/else condition on layout inflater. This solved the reuse of position variable. Now every view object has a unique position. Secondly the random button status behavior is resolved by saving the toggle button state in a separate array and keeping it outside my getview() method.