【问题标题】:Binding recycler view according to a condition根据条件绑定回收站视图
【发布时间】:2021-09-28 10:09:18
【问题描述】:

我有一个任务应用程序,人们可以在其中单击任务的复选框,任务的颜色会改变。但是我在将这个条件与视图绑定时遇到了问题。当复选框被选中时,颜色会发生变化,但是当应用程序关闭并再次打开时,复选框不会被选中并且颜色会恢复正常。在这种情况下,如何保留复选框的选中状态和文本颜色。



我的适配器类 -

 public void onBindViewHolder(@NonNull TaskHolder holder, int position) {
    Task currentTask = tasks.get(position);
    holder.a_tname.setText(currentTask.getTname());
    holder.a_tdate.setText(currentTask.getTDate());
    holder.a_ttime.setText(currentTask.getTTime());
    holder.a_tprior.setText(currentTask.getTprior());
    holder.bind(tasks.get(position));
    holder.checkbox.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            holder.bind2(tasks.get(position));
        }
    });
}
 class TaskHolder extends RecyclerView.ViewHolder  {
    private final TextView a_tname;
    private final TextView a_tdate;
    private  final TextView a_ttime;
    private final TextView a_tprior;
    ImageView priorityIndicator;
    CheckBox checkbox;


    public TaskHolder(View itemView) {
        super(itemView);
        a_tname = itemView.findViewById(R.id.a_tname);
        a_tdate=itemView.findViewById(R.id.a_tdate);
        a_ttime = itemView.findViewById(R.id.a_ttime);
        a_tprior = itemView.findViewById(R.id.a_tprior);
        priorityIndicator = itemView.findViewById(R.id.priorityIndicator);
        checkbox = itemView.findViewById(R.id.checkbox);

private void bind2(Task task){
        if(checkbox.isChecked()){
            int checkedtext = ContextCompat.getColor(a_tname.getContext(), R.color.grey);
            a_tname.setTextColor(checkedtext);
            int checkeddate =  ContextCompat.getColor(a_tdate.getContext(), R.color.grey);
            a_tdate.setTextColor(checkeddate);
            int checkedtime = ContextCompat.getColor(a_ttime.getContext(), R.color.grey);
            a_ttime.setTextColor(checkedtime);
            Toast.makeText(checkbox.getContext(), "Way to go! Now swipe to delete", Toast.LENGTH_LONG).show();
        }
        if(!checkbox.isChecked()){
            int untext = ContextCompat.getColor(a_tname.getContext(), R.color.black);
            a_tname.setTextColor(untext);
            int undate = ContextCompat.getColor(a_tdate.getContext(), R.color.black);
            a_tdate.setTextColor(undate);
            int untime = ContextCompat.getColor(a_ttime.getContext(), R.color.black);
            a_ttime.setTextColor(untime);
        }
    }

请问我是怎么做到的

【问题讨论】:

  • 选中复选框时,需要在模型类中保存复选框的状态。
  • 就像@akhilnair 所说的那样。您的模型中需要一个布尔值。这是使用您的 bind2 方法设置的。然后再次在您的 onBindViewHolder 中,您需要将其分配给复选框。 holder.checkbox.setChecked(currentTask.booleanValue);
  • 谢谢,但我的复选框已附加到回收站视图的项目布局中。如何将它保存在我的模型类中?
  • 你能详细说明你的答案吗,我对android很陌生,它会很有帮助。

标签: java android-studio android-recyclerview android-databinding


【解决方案1】:

因为在关闭和打开您的应用程序后,您的 Fragment/Activity 再次调用onCreate(随后是片段方法的正常生命周期)从零开始创建片段,您需要在关闭之前将 UI 数据存储在某处该应用程序并在以后每次调用 onViewCreated 时获取它,您可以将数据存储在 SharedPreferences 中或使用 SQLite、Room Database 或 Firebase 等数据库。

在 SharedPreferences 的情况下我可以给你一个关于如何使用它的简单示例,但我强烈建议你开始学习 Room 数据库,以防你想要存储的数据类似于数据结构,那么 Room 将为你提供良好的通过所谓的实体存储和检索数据的方法。

  1. 首先,您应该获得对 SharedPreferences 的引用(您可以将其命名为任何名称,而不是“recycleview”)
SharedPreferences shared = getContext().getSharedPreferences("recycleview",Context.MODE_PRIVATE);
SharedPreferences.Editor editor = shared.edit();
//when you need to store that a certain item got checked, might put it's position as key
String posString = Integer.valueOf(position).toString();
editor.putBoolean("item" + posString ,checkbox.isChecked).apply();
  1. 下次启动应用程序时,将数据分配给适配器时,将视图持有者绑定到数据时,检查 sharedPreferences 中是否存储旧值,如下所示:
SharedPreferences shared = context.getSharedPreferences("recycleview",Context.MODE_PRIVATE);
String keyString = Integer.valueOf(position).toString();
checkbox.setChecked(shared.getBoolean("item" + keyString ,false ));

如果 SharedPreferences 没有找到存储在其中的某个键,它会将您指定为方法 getBoolean 的第二个参数的默认值返回(在本例中为 false)。

  • 您可以从这里开始阅读有关 Room 数据库的信息:

Accessing data using Room Database| Android Developers

  • 您可以从这里开始阅读有关 SharedPerfreneces 的信息:

Save key-value data |Android Developers


更新

是的,我看到它属于回收视图项目,这就是为什么我说要使用名为 'item' + its position string 的键来存储它。

  • 如果您的回收站视图数据是一个实体或由唯一键定义,并且您想采用更复杂的回收站视图选择方式,您可以查看我的其他答案 here

  • 在前面提到的答案中,当您完成片段后,您会调用tracker.getSelection() 并检查选择了哪些键来将它们存储在您的数据库中。

  • 当你回到这个片段时,你会得到你存储在数据库中的内容并在所有这些上调用tracker.select(key),当适配器来绑定一些数据时,你会问它是否tracker.isSelected(data.get(i).getKey())并设置以返回的布尔值复选框为例。

  • 如果你仍然愿意使用 SharedPreferences,你可以添加一个 onClickListener 到持有者 rootView,每当用户点击持有者中的任何地方时,它都会触发这个 onClickListener 使用方法 holder.getAbsoluteAdapterPosition 检查它的位置并使用这个返回的位置,您将存储复选框当前是否被选中。

public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
    SharedPreferences shared ;
    SharedPreferences.Editor editor;
 //pass the to the constructor a reference to the SharedPreferences from the Fragment/Activity
    public MyAdapter(SharedPreferences shared, ...other paramters) {
        this.shared= shared;
        this.editor = shared.edit();
    }
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
         View v = LayoutInflater.from(context).inflate(R.layout.recycler_view_item, parent, false);
         View root = v.getRootView();
         MyViewHolder holder = new MyViewHolder (root);
     root.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = holder.getAbsoluteAdapterPosition();
                //when you need to store that a certain item got checked, might put it's position as key
                String posString = Integer.valueOf(position).toString();
                editor.putBoolean("item" + posString, holder.getcheckbox().isChecked).apply();
            }
        });
        return root ;
    }
    
    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        ...
        boolean isSelected = shared.getBoolean("item" + position,false )
        Checkbox checkbox = holder.getcheckbox();
        checkbox.setChecked(isSelected);
    }
    ...
}

holder.getcheckbox() 是视图持有者中应该返回复选框视图的方法

【讨论】:

  • 感谢您的回答。我正在使用 Room 数据库来存储任务,但复选框附加到回收站视图的项目布局中。这种情况我该怎么办?
  • 检查我的更新,看看它是否符合您的标准
  • 您的代码确实有效,谢谢。但是我遇到了一个问题 - 当我删除选中的项目时,它下面的项目(未选中)被选中,因为它占据了前一个项目的位置。我可以知道如何解决它。详细问题在这里 - stackoverflow.com/q/69690827/16983680
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多