根据条件绑定回收器视图

Binding recycler view according to a condition

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



我的适配器class -

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

我可以知道如何做到这一点吗

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

incase of 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 没有找到存储在其中的某个键,它 return 是您指定为方法 getBoolean 的第二个参数的默认值(在本例中为 false ).

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

Accessing data using Room Database| Android Developers

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

Save key-value data |Android Developers


更新

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

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

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

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

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

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() 是视图持有者中的一个方法,应该 return 复选框视图