Checkbox changing state when scrolling in recyclerview

拈花ヽ惹草 提交于 2020-01-05 04:44:22

问题


I made a small app that shows me a list of all the apps installed to my phone I want to add a check box to every cardview so that I can mark my favorite apps and other classification. The problem is when scrolling through the list the state of the checkbox change ex. I checked chrome and when I scrolled down then scrolled up chrome is not marked and a random app is checked. I searched for other question related to this problem but none of those solutions worked for me.

updated version of appsadapter.java

 public class AppsAdapter extends RecyclerView.Adapter<AppsAdapter.ViewHolder>{
private final SparseBooleanArray array=new SparseBooleanArray();

public class ViewHolder extends RecyclerView.ViewHolder{

    public CardView cardView;
    public ImageView imageView;
    public TextView textView_App_Name;
    public CheckBox checkBox;

    public ViewHolder (View view){

        super(view);
        checkBox = (CheckBox) view.findViewById(R.id.chckbox);
        cardView = (CardView) view.findViewById(R.id.card_view);
        imageView = (ImageView) view.findViewById(R.id.imageview);
        textView_App_Name = (TextView) view.findViewById(R.id.Apk_Name);
        //textView_App_Package_Name = (TextView) view.findViewById(R.id.Apk_Package_Name);

    }
}

private Context context1;
private List<String> stringList;

public AppsAdapter(Context context, List<String> list){

    context1 = context;
    stringList = list;
}

//viewholder initialized
@Override
public AppsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){

    View view2 = LayoutInflater.from(context1).inflate(R.layout.cardview_layout,parent,false);
    ViewHolder viewHolder = new ViewHolder(view2);
    return viewHolder;
}

//DATA IS BOUND TO VIEWS
private SparseBooleanArray sba = new SparseBooleanArray();
@Override
public void onBindViewHolder(ViewHolder viewHolder,final int position){

    viewHolder.setIsRecyclable(false);
    ApkInfoExtractor apkInfoExtractor = new ApkInfoExtractor(context1);
    final String ApplicationPackageName = (String) stringList.get(position);

    //calling apps name and icon
    String ApplicationLabelName = apkInfoExtractor.GetAppName(ApplicationPackageName);
    Drawable drawable = apkInfoExtractor.getAppIconByPackageName(ApplicationPackageName);

    //setting app name and icon for every card
    viewHolder.textView_App_Name.setText(ApplicationLabelName);
    viewHolder.imageView.setImageDrawable(drawable);
    viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            sba.put(position, !sba.get(position));
            notifyDataSetChanged();
        }
    });
    viewHolder.checkBox.setChecked(sba.get(position));


    /*Adding click listener on CardView to open clicked application directly from here
    viewHolder.cardView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            Intent intent = context1.getPackageManager().getLaunchIntentForPackage(ApplicationPackageName);
            if(intent != null){
                context1.startActivity(intent);
            }
            else {
                Toast.makeText(context1,ApplicationPackageName + " Error, Please Try Again.", Toast.LENGTH_LONG).show();
            }
        }
    });*/
}

@Override
public int getItemCount(){
    return stringList.size();
}

}


回答1:


That is because in the recycler view, item views are re used to show new data. You have to add a variable in your data item that holds the state of the checkbox at a particular position. Then in the onBindViewHolder you can check the value of the tracking variable and set the state of the checkbox like yourCheckbox.setchecked(item.getSelected()) set the tracking variable value in the onCheckChanged method




回答2:


Set checkbox inside checkBox onclickListener

holder.mCheckBox.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            CheckBox checkBox = (CheckBox) view;
            mDataModel = (DataModel) checkBox.getTag();
            mDataModel.setChecked(checkBox.isChecked());
            arrayList.get(position).setChecked(checkBox.isChecked());

        }
    });



回答3:


set view onclicklistener in BindViewholder method so you can use the current position of item as in

 private SparseBooleanArray sba = new SparseBooleanArray();
    @Override
    public void onBindViewHolder(ViewHolder viewHolder,final int position){

        viewHolder.setIsRecyclable(false);
        ApkInfoExtractor apkInfoExtractor = new ApkInfoExtractor(context1);
        final String ApplicationPackageName = (String) stringList.get(position);

        //calling apps name and icon
        String ApplicationLabelName = apkInfoExtractor.GetAppName(ApplicationPackageName);
        Drawable drawable = apkInfoExtractor.getAppIconByPackageName(ApplicationPackageName);

        //setting app name and icon for every card
        viewHolder.textView_App_Name.setText(ApplicationLabelName);
        viewHolder.imageView.setImageDrawable(drawable);
        viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    sba.put(position,!sba.get(position));
                    notifyDataSetChanged();
                }
            });
        viewHolder.checkBox.setChecked(sba.get(position));
    }


来源:https://stackoverflow.com/questions/48534179/checkbox-changing-state-when-scrolling-in-recyclerview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!