简体   繁体   中英

Android: Listview don't save a state of checkbox

I check all topic with similar problem, but I stil stay in deadpoint. I have a listview with contact list, but when i scroll down and scroll up listview don't save a state of my choices. All checkboxes was setting on false. When i debug i see, when i scrolled listview, my onClickListener thinking that checkbox was signed and reset this. I do everything, other array with position boolean, etc etc and I still don't know what to do :( I will be very gratefull for any help:)

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        readContacts();
        Contact_Database dbhandler = new Contact_Database(
                getApplicationContext(), null, null, 1);
        numbers.addAll( dbhandler.getAllNumbers());
        System.out.println("onCreate");
        ListView lv = getListView();
        registerForContextMenu(lv);
        lv.setTextFilterEnabled(true);
        lv.clearChoices();
        MyAdapter adapter = (new MyAdapter(this, R.layout.contact_list_sms, contacts));
        adapter.notifyDataSetChanged();
        lv.setAdapter(adapter);

    }

    /**
     * When I destroy intent i send request to database, faster!
     */

    @Override
    protected void onDestroy() {
        super.onDestroy();
        for (int i = 0; i < numbers.size(); ++i)
            System.out.println("@@@@" + numbers.get(i));

        swap_contacts();

    }

class MyAdapter extends ArrayAdapter<Contact> {

        LayoutInflater inflat;

        public MyAdapter(Context context, int textViewResourceId,
                ArrayList<Contact> objects) {
            super(context, textViewResourceId, objects);
            inflat = LayoutInflater.from(context);
            System.out.println("LOLLLLL");
            notifyDataSetChanged();

        }

        @Override
        public int getItemViewType(int position) {
            return (position == this.getCount() - 1) ? 1 : 0;
        }

        @Override
        public int getViewTypeCount() {
            return 2;
        }

        // if that contact exist in database? numbers, in onCreate method
        // i init this with saved position from databse
        private boolean exist(String x) {
            for (int i = 0; i < numbers.size(); i++)
                if (numbers.get(i).compareTo(x) == 0)
                    return true;
            return false;
        }

        @SuppressLint("NewApi")
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            System.out.println("ROWS !!! ->" + numbers.size());
            ViewHolder holder = null;
            if (convertView == null) {
                holder = new ViewHolder();
                convertView = inflat.inflate(R.layout.contact_row, null);
                holder.textView1 = (TextView) convertView
                        .findViewById(R.id.name);
                holder.textView2 = (TextView) convertView
                        .findViewById(R.id.number);
                holder.on_off = (CheckBox) convertView
                        .findViewById(R.id.enable);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            Contact it = contacts.get(position);
            Log.v("XXX", holder.toString());
            if (it != null) {
                holder.textView1.setText(contacts.get(position).name);
                holder.textView2.setText(contacts.get(position).phone);
                // update state of checbox from database
                if (exist(contacts.get(position).phone))
                    holder.on_off.setChecked(true);
                else
                    holder.on_off.setChecked(false);
            }

            final int element_position = position;

            holder.on_off
                    .setOnCheckedChangeListener(new OnCheckedChangeListener() {
                        // update list when we click on it
                        @Override
                        public void onCheckedChanged(CompoundButton buttonView,
                                boolean isChecked) {
                            String nr_telefonu = contacts.get(element_position).phone;
                            if (isChecked) {
                                numbers.add(nr_telefonu);
                            } else {
                                numbers.remove(nr_telefonu);
                            }
                        }
                    });
            return convertView;
        }


        @Override
        public Contact getItem(int position) {
            return contacts.get(position);
        }

        private class ViewHolder {
            TextView textView1, textView2;
            CheckBox on_off;

            public String toString() {
                return "-";
            }
        }
    }

List does not save it state while scrolling , because each time new object is created for row item. So you need to explicitly save the state of CheckBox with help of Pojo class(Setter and getter).

in getView() method you need to check the value for each checkbox.

@Override
        public View getView(int position, View convertView, ViewGroup parent) {
////////////////////

and on setOnCheckedChangeListener you need to save the state of checkbox

                  holder.on_off
                    .setOnCheckedChangeListener(new OnCheckedChangeListener() {
                        // update list when we click on it
                        @Override
                        public void onCheckedChanged(CompoundButton buttonView,
                                boolean isChecked) {
                        // need to save the state

for more details please refer to this below blog

http://amitandroid.blogspot.in/2013/03/android-listview-with-checkbox-and.html

you can change it according to your requirement.

Thank's for answer :) I create a array stan with state for every checkbox button. Tommorrow i will try rebuild all my class like the list on the blog, mayby this help me.

But when I do this : save state:

holder.on_off
                    .setOnCheckedChangeListener(new OnCheckedChangeListener() {
                        // update list when we click on it
                        // this.setChecked(stan[position]);
                        @Override
                        public void onCheckedChanged(CompoundButton buttonView,
                                boolean isChecked) {
                            String nr_telefonu = p.get(element_position).phone;
                            buttonView.setChecked(stan[element_position]);

                            stan[element_position] = isChecked;
                        }
                    });

Refresh state of button

if (it != null) {
                holder.textView1.setText(contacts.get(position).name);
                holder.textView2.setText(contacts.get(position).phone);
                // update state of checbox from database

                    holder.on_off.setChecked(stan[position]);
            }

I still stand In dead point, nothing is changed

I've posted the solution to this problem below which I spent a lot of time finding and it works for me!

 public class RowAdapter extends ArrayAdapter<Rows> { Context context; int layoutResourceId; ArrayList<Rows> data; boolean[] checkBoxState; RowHolder rowHolder; public RowAdapter(Context context, int layoutResourceId, ArrayList<Rows> data) { super(context, layoutResourceId, data); this.layoutResourceId = layoutResourceId; this.context = context; this.data = data; checkBoxState = new boolean[data.size()]; } @Override public View getView(final int position, View convertView, ViewGroup parent) { View row = convertView; RowHolder holder = null; if(row == null) { LayoutInflater inflater = ((Activity)context).getLayoutInflater(); row = inflater.inflate(layoutResourceId, parent, false); holder = new RowHolder(); holder.textView1 = (TextView)row.findViewById(R.id.textView1); holder.textView2 = (TextView)row.findViewById(R.id.textView2); holder.textView3 = (TextView)row.findViewById(R.id.textView3); holder.textView4 = (TextView)row.findViewById(R.id.textView4); holder.checkBox=(CheckBox) row.findViewById(R.id.checkBox1); row.setTag(holder); } else{ holder = (RowHolder)row.getTag(); } Rows rows = data.get(position); holder.textView1.setText(rows.address); holder.textView2.setText(rows.tenancy); holder.textView3.setText(rows.location); holder.textView4.setText(rows.name); holder.checkBox.setChecked(checkBoxState[position]); holder.checkBox.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if(((CheckBox)v).isChecked()) checkBoxState[position]=true; else checkBoxState[position]=false; } }); return row; } static class RowHolder { TextView textView1; TextView textView2; TextView textView3; TextView textView4; CheckBox checkBox; } } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM