简体   繁体   中英

Checkbox listview scrolling issue

I am unable to properly check and uncheck (on clicking select all and unselect all respectively) the checkbox if listview have more items( more items in the sense items exceeding a mobile screen page). Only first page items get checked or unchecked on clicking the select all or unselect checkbox.

Below is my Activity class. Please let me know what changes i need to make for this code.

    public class ListCheck extends AppCompatActivity {
    ListView lv_list;
    ArrayList<ListCheckPojo> listCheckPojos = new ArrayList<>();
    ListCheckAdapter listCheckAdapter;
    CheckBox cb_item_list,cb_list;
    View view;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list_check);

        lv_list = findViewById(R.id.lv_list);
        listCheckAdapter = new ListCheckAdapter(this,listCheckPojos);
        lv_list.setAdapter(listCheckAdapter);
        cb_list = findViewById(R.id.cb_list);

        listCheckPojos.add(new ListCheckPojo(false,"a1"));
        listCheckPojos.add(new ListCheckPojo(false,"a1"));
        listCheckPojos.add(new ListCheckPojo(false,"a1"));
        listCheckPojos.add(new ListCheckPojo(false,"a1"));
        listCheckPojos.add(new ListCheckPojo(false,"a1"));
        listCheckPojos.add(new ListCheckPojo(false,"a1"));
        listCheckPojos.add(new ListCheckPojo(false,"a1"));
        listCheckPojos.add(new ListCheckPojo(false,"a1"));
        listCheckPojos.add(new ListCheckPojo(false,"a1"));
        listCheckPojos.add(new ListCheckPojo(false,"a1"));

        cb_list.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if(cb_list.isChecked()){
                    cb_list.setText("Unselect all");
                    for(int i = 0; i<lv_list.getChildCount();i++){
                        view = lv_list.getChildAt(i);
                        cb_item_list = view.findViewById(R.id.cb_item_list);
                        cb_item_list.setChecked(true);
                    }

                }
                else {
                    cb_list.setText("select all");
                    for(int i = 0; i<lv_list.getChildCount();i++){
                        view = lv_list.getChildAt(i);
                        cb_item_list = view.findViewById(R.id.cb_item_list);
                        cb_item_list.setChecked(false);
                        lv_list.setItemChecked(i,false);

                    }
                }
            }
        });

    }
}

This is my adapter class.

public class ListCheckAdapter extends ArrayAdapter<ListCheckPojo> {
    ArrayList<ListCheckPojo> listCheckPojos = new ArrayList<>();
    private SparseBooleanArray mSelectedItem =  new SparseBooleanArray(listCheckPojos.size());
    private boolean isAllowOnCheckChange = true;
    Context context;
    public ListCheckAdapter(@NonNull Context context,    ArrayList<ListCheckPojo> listCheckPojos) {
        super(context, R.layout.item_list_check, listCheckPojos);
        this.context = context;
        this.listCheckPojos = listCheckPojos;
    }

    @Override
    public int getCount() {
        return listCheckPojos.size();
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        ListCheckPojo listCheckPojo ;
        CheckBox cb_item_list;
        TextView tv_item_list;
        if(convertView == null){
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list_check,parent,false);
        }
        listCheckPojo = listCheckPojos.get(position);
        cb_item_list =  convertView.findViewById(R.id.cb_item_list);
        tv_item_list = convertView.findViewById(R.id.tv_item_list);
        tv_item_list.setText(listCheckPojo.getTv_item_list());

        isAllowOnCheckChange = false;
        cb_item_list.setChecked(mSelectedItem.get(position));
        isAllowOnCheckChange = true;

        cb_item_list.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
                if (isAllowOnCheckChange)
                    mSelectedItem.put(position, isChecked);
            }
        });

        return convertView;
    }
}

This my main xml activity.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/ll"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    tools:context=".Activity.Why">

    <CheckBox
        android:id="@+id/cb_list"
        android:layout_width="150dp"
        android:layout_height="50dp"
        android:text="Select all"/>
    <ListView
        android:id="@+id/lv_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

This is my item xml.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_weight="0"
    android:layout_height="wrap_content">
    <CheckBox
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp"
        android:id="@+id/cb_item_list"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_weight="1"/>
    <TextView
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp"
        android:gravity="center"
        android:id="@+id/tv_item_list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Autobrix"
        android:layout_weight="1"/>

</LinearLayout>

Below is my Pojo class.

public class ListCheckPojo {
    boolean cb_item_list;
    String tv_item_list;

    public ListCheckPojo(boolean cb_item_list, String tv_item_list) {
        this.cb_item_list = cb_item_list;
        this.tv_item_list = tv_item_list;
    }

    public boolean isCb_item_list() {
        return cb_item_list;
    }

    public void setCb_item_list(boolean cb_item_list) {
        this.cb_item_list = cb_item_list;
    }

    public String getTv_item_list() {
        return tv_item_list;
    }

    public void setTv_item_list(String tv_item_list) {
        this.tv_item_list = tv_item_list;
    }
}

Please help me with some code snippet. Thanks in advance.

Try below changes in adapter:

@NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        ListCheckPojo listCheckPojo ;
        CheckBox cb_item_list;
        TextView tv_item_list;
        if(convertView == null){
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list_check,parent,false);
        }
        listCheckPojo = listCheckPojos.get(position);
        cb_item_list =  convertView.findViewById(R.id.cb_item_list);
        tv_item_list = convertView.findViewById(R.id.tv_item_list);
        tv_item_list.setText(listCheckPojo.getTv_item_list());

        cb_item_list.setOnCheckedChangeListener(null) //change here
        cb_item_list.setChecked(mSelectedItem.get(position));


        cb_item_list.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {

                    mSelectedItem.put(position, isChecked);
                    notifyDataSetChanged(); //change here
            }
        });

        return convertView;
    }

In Activity:

cb_list.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if(cb_list.isChecked()){
                    cb_list.setText("Unselect all");
                    for(int i = 0; i<lv_list.getChildCount();i++){
                        view = lv_list.getChildAt(i);
                        cb_item_list = view.findViewById(R.id.cb_item_list);
                        cb_item_list.setChecked(true);
                    }

                }
                else {
                    cb_list.setText("select all");
                    for(int i = 0; i<lv_list.getChildCount();i++){
                        view = lv_list.getChildAt(i);
                        cb_item_list = view.findViewById(R.id.cb_item_list);
                        cb_item_list.setChecked(false);
                        lv_list.setItemChecked(i,false);

                    }
                }
              listCheckAdapter.notifyDataSetChanged(); //change here
            }
        });

Hope this will help!!

I got the answer for this. I just have done it by using recyclerview and added two more methods. Add this in OnBindViewHolder of adapter class.

if (isSelectedAll){
            if (holder.cb_why_item.isChecked()){
                holder.cb_why_item.setChecked(false);
            }else {
                holder.cb_why_item.setChecked(false);
            }
        }else {
            if (holder.cb_why_item.isChecked()){
                holder.cb_why_item.setChecked(true);
            }else {
                holder.cb_why_item.setChecked(true);
            }
        }

Add the below methods in adapter class.

 public void selectAll(Boolean yes){
    Log.e("onClickSelectAll","yes");
    isSelectedAll=yes;
    notifyDataSetChanged();
}

public void unSelectAll(Boolean no){
    Log.e("onClickSelectAll","no");
    isSelectedAll=no;
    notifyDataSetChanged();
}

Replace onSetCheckedListener(which is in question- activity class) with the below code in activity class.

  cb_why.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {
           if (cb_why.isChecked()){
               cb_why.setChecked(true);
               cb_why.setText("unselect all");
               whyAdapter.unSelectAll(false);

           }else {
               cb_why.setText("select all");
               cb_why.setChecked(false);
               whyAdapter.selectAll(true);
           }
       }
   });

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