【问题标题】:Checkbox changing state when scrolling in recyclerview在回收站视图中滚动时复选框更改状态
【发布时间】:2018-01-31 12:56:52
【问题描述】:

我制作了一个小应用程序,它显示了我手机上安装的所有应用程序的列表我想在每个卡片视图中添加一个复选框,以便我可以标记我最喜欢的应用程序和其他分类。问题是当滚动列表时,复选框的状态会发生变化。我检查了 chrome,当我向下滚动然后向上滚动时,没有标记 chrome,并检查了一个随机应用程序。我搜索了与此问题相关的其他问题,但这些解决方案都不适合我。

appadapter.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();
}

}

【问题讨论】:

  • 在将适配器设置为您的 recylerview mRecyclerView.setItemViewCacheSize(yourList.size()); 之前尝试在活动中添加这一行
  • @MohammedFarhan 你能解释一下这条线会做什么吗?
  • RecylerView 在每 9 个项目后回收相同的视图。因此,如果您传递给适配器的数据集超过 9 个项目,并且对特定项目所做的更改(选中复选框)将在 9 个项目后重新出现。因此,如果您添加该行,它将Set the number of offscreen views to retain before adding them to the potentially shared recycled view pool. The offscreen view cache stays aware of changes in the attached adapter.

标签: android checkbox android-recyclerview


【解决方案1】:

这是因为在回收站视图中,项目视图被重新使用来显示新数据。您必须在数据项中添加一个变量,该变量将复选框的状态保存在特定位置。然后在onBindViewHolder 中可以检查跟踪变量的值并设置复选框的状态,如yourCheckbox.setchecked(item.getSelected())onCheckChanged 方法中设置跟踪变量值

【讨论】:

  • 嗨!你能告诉我一个我可以遵循的简单代码吗?很抱歉打扰您
【解决方案2】:

BindViewholder 方法中设置视图onclicklistener,以便您可以使用项目的当前位置

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

【讨论】:

  • 您好,先生!我使用你的代码,它给出了一个错误,说'局部变量位置是从内部类中访问的,需要声明为 final',所以我将 int 位置更改为 final int 位置以解决错误,但复选框问题仍然存在。
  • 问题仍然存在。添加final会从代码中删除错误,但复选框的状态仍在变化。
  • 我用这个替换了代码,它有一个错误说'put(int, boolean)in SparceBooleanArray cannot be applied to (boolean)'
  • 没有解决问题。复选框仍在更改状态
  • 很高兴我能帮上忙!快乐编码:)
【解决方案3】:

在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());

        }
    });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    • 1970-01-01
    相关资源
    最近更新 更多