I have a tasks app where the person can click on the checkbox of the task and the colour of the task will change. But i'm having a problem with binding this condition with the view. When the checkbox is checked, the colour changes but when the app is closed and opened again, the checkbox is not checked and the color goes back to normal. How can i retain the checked state of the checkbox and the text colour in this case.
My Adapter 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);
}
}
May i please know how this can be done
Because after closing and opening of your app, your Fragment/Activity calls onCreate
again (which follows with the normal lifecycle of fragment methods') creating the fragment from zero, what you need is to store UI data somewhere before closing the app and fetch it later everytime onViewCreated
is called, you can store your data in SharedPreferences or using a database like SQLite, Room Database or Firebase.
incase of SharedPreferences I can give you a quick example on how to use it but I highly recommend you start learning about Room database in case if the data you want to store would be like data structures, then Room will provide you with good ways to store and retrieve your data through what it calls entities.
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();
SharedPreferences shared = context.getSharedPreferences("recycleview",Context.MODE_PRIVATE);
String keyString = Integer.valueOf(position).toString();
checkbox.setChecked(shared.getBoolean("item" + keyString ,false ));
where if the SharedPreferences didn't find a certain key stored in it, it returns the default value that you specified as second parameter to the method getBoolean
(which in this case false).
Accessing data using Room Database| Android Developers
Save key-value data |Android Developers
yes I see it belongs to the recycle view items that's why I said to store it with a key named 'item' + its position string
.
if your recycler view data is an entity or defined by a unique key and you want to resort to a more complicate way of recycler view selection you can check my other answer here.
in the previously mentioned answer, when you're finished with your fragment you would call tracker.getSelection()
and check which keys got selected to store them in your database.
when you come back to this fragment, you will get what you stored in your database and call tracker.select(key)
on all of them, where when the adapter comes to bind some data you would ask it if tracker.isSelected(data.get(i).getKey())
and set the checkbox by the returned boolean value as an example.
if you still willing to use the SharedPreferences, you could add an onClickListener
to the holder rootView, whenever the user click anywhere in the holder it shall trigger this onClickListener
to check its position by using the method holder.getAbsoluteAdapterPosition
and using this returned position you would store whether the checkbox is currently checked or not .
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);
}
...
}
where holder.getcheckbox()
is a method in the view holder that should return the checkbox view