Only two checkbox can select user , how to achieve this? - android

This is screenshot
I want only select two checkboxes from the listing of checkboxes........................................................................................................................................................................................................................................................................................
Below is my code
public class OfferItemsAdapter extends RecyclerView.Adapter<OfferItemsAdapter.ViewHolder> {
private ArrayList<TaskListModel.Option> mDataset;
String strFreeItem;
OfferItemsAdapter(ArrayList<TaskListModel.Option> reviwsLists, String strFreeItem) {
mDataset = reviwsLists;
this.strFreeItem = strFreeItem;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.addon_list_cart_item, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.cbProduct.setText(mDataset.get(position).getItemName());
holder.tvProductPrice.setVisibility(View.GONE);
if (strFreeItem.equalsIgnoreCase("1")) {
if (mDataset.get(position).isChecked()) {
holder.cbProduct.setChecked(true);
selectedItems.add(mDataset.get(position).getItemID());
} else {
holder.cbProduct.setChecked(false);
selectedItems.remove(mDataset.get(position).getItemID());
}
}
holder.cbProduct.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (strFreeItem.equalsIgnoreCase("1")) {
if (selectedItems.size() == 1 && selectedItems.contains(mDataset.get(position).getItemID())) {
mDataset.get(position).setChecked(false);
} else {
mDataset.get(position).setChecked(true);
}
}
notifyDataSetChanged();
Log.e("selectedItems.toString()............",""+selectedItems.toString());
}
});
}
#Override
public int getItemCount() {
return mDataset == null ? 0 : mDataset.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public View mainView;
TextView tvProductPrice;
CheckBox cbProduct;
public ViewHolder(View v) {
super(v);
mainView = v;
tvProductPrice = v.findViewById(R.id.tvProductPrice);
cbProduct = v.findViewById(R.id.cbProduct);
}
}
}

First of all, you should use setOnCheckedChangeListener instead of setOnClickListener.
And use setOnCheckedChangeListener and check selectedItems size everytime user check the checkbox like the following.
holder.cbProduct.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
if (isChecked){
if(selectedItems.size()<2){
selectedItems.add(mDataset.get(position).getItemID());
mDataset.get(position).setChecked(true);
}else{
holder.cbProduct.setChecked(false);
// here you can show a toast or log that user can't select more than two items.
}
}else{
selectedItems.remove(mDataset.get(position).getItemID());
mDataset.get(position).setChecked(false);
}
}
}
);

Related

How to change visibility of the buttons in the others items in Recyclerview?

I have recyclerview with the buttons inside of items. When I click one button in one of them I want to hide buttons in others items. I know how to do it in same item where I clicked button, but I no have idea how to do it in other things without touching them. How to do it? I tried with the boolean in the ViewHolder, but it doesn't work.
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ListViewHolder> {
private List<Task> tasks;
private boolean visible;
public class ListViewHolder extends RecyclerView.ViewHolder {
private TextView nameTextView, idTextView;
private Button travelButton, travellingButton, workButton, stopButton;
public ListViewHolder(#NonNull View itemView) {
super(itemView);
nameTextView = itemView.findViewById(R.id.name_text_view);
idTextView = itemView.findViewById(R.id.id_text_view);
travelButton = itemView.findViewById(R.id.travel_button);
travellingButton = itemView.findViewById(R.id.travelling_button);
workButton = itemView.findViewById(R.id.work_button);
stopButton = itemView.findViewById(R.id.stop_button);
if (visible == true) {
travelButton.setVisibility(View.GONE);
}
else {
travelButton.setVisibility(View.VISIBLE);
}
}
}
#NonNull
#Override
public ListViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list, parent, false);
return new ListViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ListAdapter.ListViewHolder holder, final int position) {
Task task = tasks.get(position);
holder.nameTextView.setText(task.getName());
holder.idTextView.setText(String.valueOf(task.getId()));
holder.travelButton.setVisibility(View.VISIBLE);
holder.travelButton.setText(R.string.start_travel);
holder.travellingButton.setText(R.string.travelling);
holder.travelButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.travelButton.setVisibility(View.GONE);
holder.travellingButton.setVisibility(View.VISIBLE);
holder.workButton.setVisibility(View.VISIBLE);
holder.itemView.setBackgroundColor(Color.parseColor("#FFECB3"));
visible = true;
}
});
holder.workButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.workButton.setText(R.string.working);
holder.travelButton.setVisibility(View.GONE);
holder.travellingButton.setVisibility(View.GONE);
holder.stopButton.setVisibility(View.VISIBLE);
holder.itemView.setBackgroundColor(Color.parseColor("#FFCDD2"));
}
});
holder.stopButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.travelButton.setText(R.string.start_travel);
holder.travelButton.setVisibility(View.VISIBLE);
holder.travellingButton.setVisibility(View.GONE);
holder.workButton.setText(R.string.work);
holder.workButton.setVisibility(View.GONE);
holder.stopButton.setVisibility(View.GONE);
holder.itemView.setBackgroundColor(Color.TRANSPARENT);
visible = false;
}
});
}
#Override
public int getItemCount() {
return tasks == null ? 0 : tasks.size();
}
public void setTasks(List<Task> tasks) {
this.tasks = tasks;
notifyDataSetChanged();
}
}
Ok, I found the answer to my question. I just made an interface that informs activity about the need to refresh the adapter and it works.
ListAdapter:
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ListViewHolder> {
private List<Task> tasks;
private int travelButtonVisibility=-1;
private OnButtonClickListener mOnButtonClickListener;
public void setOnButtonClickListener(OnButtonClickListener onButtonClickListener) {
mOnButtonClickListener = onButtonClickListener;
}
public class ListViewHolder extends RecyclerView.ViewHolder {
private TextView nameTextView, idTextView;
private Button travelButton, travellingButton, workButton, stopButton;
public ListViewHolder(#NonNull View itemView) {
super(itemView);
nameTextView = itemView.findViewById(R.id.name_text_view);
idTextView = itemView.findViewById(R.id.id_text_view);
travelButton = itemView.findViewById(R.id.travel_button);
travellingButton = itemView.findViewById(R.id.travelling_button);
workButton = itemView.findViewById(R.id.work_button);
stopButton = itemView.findViewById(R.id.stop_button);
}
}
#NonNull
#Override
public ListViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list, parent, false);
return new ListViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ListAdapter.ListViewHolder holder, final int position) {
final Task task = tasks.get(position);
holder.nameTextView.setText(task.getName());
holder.idTextView.setText(String.valueOf(task.getId()));
holder.travelButton.setText(R.string.start_travel);
holder.travellingButton.setText(R.string.travelling);
if (travelButtonVisibility <= 0) {
holder.travelButton.setVisibility(View.VISIBLE);
}
else if (position == travelButtonVisibility){
holder.travelButton.setVisibility(View.GONE);
holder.travellingButton.setVisibility(View.VISIBLE);
holder.workButton.setVisibility(View.VISIBLE);
holder.itemView.setBackgroundColor(Color.parseColor("#FFECB3"));
}
holder.travelButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mOnButtonClickListener.onTravelButtonClick();
travelButtonVisibility = position;
holder.travelButton.setVisibility(View.GONE);
}
});
holder.workButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.workButton.setText(R.string.working);
holder.travellingButton.setVisibility(View.GONE);
holder.stopButton.setVisibility(View.VISIBLE);
holder.itemView.setBackgroundColor(Color.parseColor("#FFCDD2"));
}
});
holder.stopButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.travelButton.setText(R.string.start_travel);
holder.travellingButton.setVisibility(View.GONE);
holder.workButton.setText(R.string.work);
holder.workButton.setVisibility(View.GONE);
holder.stopButton.setVisibility(View.GONE);
holder.itemView.setBackgroundColor(Color.TRANSPARENT);
travelButtonVisibility = -1;
notifyDataSetChanged();
}
});
}
#Override
public int getItemCount() {
return tasks == null ? 0 : tasks.size();
}
public void setTasks(List<Task> tasks) {
this.tasks = tasks;
notifyDataSetChanged();
}
public interface OnButtonClickListener {
void onTravelButtonClick();
}
}
MainActvity:
private void initList() {
listAdapter = new ListAdapter();
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(listAdapter);
recyclerView.setHasFixedSize(true);
listAdapter.setTasks(tasks);
listAdapter.setOnButtonClickListener(new ListAdapter.OnButtonClickListener() {
#Override
public void onTravelButtonClick() {
recyclerView.setAdapter(listAdapter);
Log.e("MainActivity", "Travel Button");
}
});
}
add this to onBindViewHolder:
holder.travellingButton.setVisibility(visible? View.VISIBLE : View.GONE);
and after changing "visible" call
notifyItemRangeChanged(0, getItemCount())
Try something like this instead:
public class ListViewHolder extends RecyclerView.ViewHolder {
private optionSelected = 0
public ListViewHolder(#NonNull View itemView) {
super(itemView);
nameTextView = itemView.findViewById(R.id.name_text_view);
idTextView = itemView.findViewById(R.id.id_text_view);
travelButton = itemView.findViewById(R.id.travel_button);
travellingButton = itemView.findViewById(R.id.travelling_button);
workButton = itemView.findViewById(R.id.work_button);
stopButton = itemView.findViewById(R.id.stop_button);
if (visible == true) {
travelButton.setVisibility(View.GONE);
}
else {
travelButton.setVisibility(View.VISIBLE);
}
}
}
#NonNull
#Override
public ListViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list, parent, false);
return new ListViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ListAdapter.ListViewHolder holder, final int position) {
Task task = tasks.get(position);
if(option == 0 && position == 0){
holder.nameTextView.setText(task.getName());
holder.idTextView.setText(String.valueOf(task.getId()));
holder.travelButton.setVisibility(View.VISIBLE);
holder.travelButton.setText(R.string.start_travel);
holder.travellingButton.setText(R.string.travelling);
} else if(option == 1 && position == 1){
// do Something with your view
} else {
// do something with your view
}
holder.travelButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
option = 1
notifyDataChanged()
}
});
holder.workButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
option = 2
notifyDataChanged()
}
});
holder.stopButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
option = 3
notifyDataChanged()
}
});
}
#Override
public int getItemCount() {
return tasks == null ? 0 : tasks.size();
}
public void setTasks(List<Task> tasks) {
this.tasks = tasks;
notifyDataSetChanged();
}
}
You're setting different visibility depending on which button is clicked. I recommend using an enum instead of a boolean to store the state of your list and update the state on each button click.
Define an enum in your Adapter and create a member variable using it:
private List<Task> task;
private ListState state = ListState.showButton1; // Set a default value
// I used "showButton" but this can be any set a values that represent your various states
private enum ListState{
showButton1, showButton2, showButton3
}
Inside of your onBindViewHolder:
// Set the state of the view holder
switch(state){
case showButton1:
// Set your corresponding visibility changes on your view holder here
break;
case showButton2:
// Set your corresponding visibility changes on your view holder here
break;
case showButton3:
// Set your corresponding visibility changes on your view holder here
break;
}
// Make sure to update the adapter whenever a button is clicked
holder.button1.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
// Set the state and notify the adapter
state = ListState.showButton2;
notifyDataSetChanged();
}
})
// Add click listeners for your remaining buttons
// ...
Please try below code, it will initially display all travellingButton and when you click travellingButton of one of the list item, travellingButton of other items will hide.
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ListViewHolder> {
private List<Task> tasks;
private int travelButtonVisibility=-1;
public class ListViewHolder extends RecyclerView.ViewHolder {
private TextView nameTextView, idTextView;
private Button travelButton, travellingButton, workButton, stopButton;
public ListViewHolder(#NonNull View itemView) {
super(itemView);
nameTextView = itemView.findViewById(R.id.name_text_view);
idTextView = itemView.findViewById(R.id.id_text_view);
travelButton = itemView.findViewById(R.id.travel_button);
travellingButton = itemView.findViewById(R.id.travelling_button);
workButton = itemView.findViewById(R.id.work_button);
stopButton = itemView.findViewById(R.id.stop_button);
}
}
#NonNull
#Override
public ListViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list, parent, false);
return new ListViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ListAdapter.ListViewHolder holder, final int position) {
Task task = tasks.get(position);
holder.nameTextView.setText(task.getName());
holder.idTextView.setText(String.valueOf(task.getId()));
holder.travelButton.setText(R.string.start_travel);
holder.travellingButton.setText(R.string.travelling);
if(travelButtonVisibility==-1 || travelButtonVisibility==position){
{
holder.travelButton.setVisibility(View.VISIBLE);
}else{
holder.travelButton.setVisibility(View.GONE);
}
holder.travelButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.travelButton.setVisibility(View.GONE);
holder.travellingButton.setVisibility(View.VISIBLE);
holder.workButton.setVisibility(View.VISIBLE);
holder.itemView.setBackgroundColor(Color.parseColor("#FFECB3"));
travelButtonVisibility=position
notifyDataSetChanged();
}
});
holder.workButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.workButton.setText(R.string.working);
holder.travelButton.setVisibility(View.GONE);
holder.travellingButton.setVisibility(View.GONE);
holder.stopButton.setVisibility(View.VISIBLE);
holder.itemView.setBackgroundColor(Color.parseColor("#FFCDD2"));
}
});
holder.stopButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.travelButton.setText(R.string.start_travel);
holder.travelButton.setVisibility(View.VISIBLE);
holder.travellingButton.setVisibility(View.GONE);
holder.workButton.setText(R.string.work);
holder.workButton.setVisibility(View.GONE);
holder.stopButton.setVisibility(View.GONE);
holder.itemView.setBackgroundColor(Color.TRANSPARENT);
visible = false;
}
});
}
#Override
public int getItemCount() {
return tasks == null ? 0 : tasks.size();
}
public void setTasks(List<Task> tasks) {
this.tasks = tasks;
notifyDataSetChanged();
}
}
Hope this will help.

Android RecyclerView checkbox checks itself

I have a RecyclerView which has a checkbox and textview.Numbers 10,20,30,40... till 500 should be shown in textview.The Checked checkboxes should add the numbers in the textview corresponding to the checkbox.For eg. if User checks the value 10 only, the textView would show 10. If user checks 20 as well, then
TextView would show 30 ( 20 +10).
If user uncheck 10 again, the TextView would show 20, and so on.When i click on checkbox some random checkbox is also checked.I tried one solution in stackoverflow. It did not work.I am stuck with this.Please help me..Here is my code:
RecyclerAdapter.java:
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.RecyclerHolder>
{
#NonNull
#Override
public RecyclerHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new RecyclerHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_lyt,parent,false));
}
#Override
public void onBindViewHolder(#NonNull RecyclerHolder holder, final int position) {
holder.number.setText(Integer.toString((Integer) alldata.get(position)));
final String text=holder.number.getText().toString();
holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.e("Checked","Checked");
if(checkeddata!=null)
{
if (checkeddata.size()==0)
{
checkeddata.add(text);
}
else {
if(checkeddata.contains(text))
{
checkeddata.remove(text);
}
else {
checkeddata.add(text);
}
}
Iterator iterator=checkeddata.iterator();
int sumnumber=0;
while (iterator.hasNext())
{
sumnumber= sumnumber+Integer.parseInt((String) iterator.next());
}
sum.setText(Integer.toString(sumnumber));
}
}
});
}
#Override
public int getItemCount() {
return alldata.size();
}
public class RecyclerHolder extends RecyclerView.ViewHolder
{
TextView number;
CheckBox checkBox;
public RecyclerHolder(View itemView) {
super(itemView);
number=itemView.findViewById(R.id.number);
checkBox=itemView.findViewById(R.id.check);
}
}
}
public void data()
{
int g=1;
for(int i=10;i<=500;i++)
{
if((i/10)==g)
{
g=g+1;
alldata.add(i);
}
}
}
recycler_lyt.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:layout_width="150dp"
android:layout_height="wrap_content"
android:id="#+id/number"
android:textSize="20sp"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/check"
android:checked="false"
app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>
It's normal. You are not setting your checkbox selected or not. You are selecting one and View holder keeps it selected
You may look at my example. You can do something like that:
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
final Data data = myItems.get(position);
//in some cases, it will prevent unwanted situations
holder.checkBox.setOnCheckedChangeListener(null);
//if true, your checkbox will be selected, else unselected
holder.checkBox.setChecked(data.isSelected());
holder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//set your object's last status
data.setSelected(isChecked);
}
});
}
inside your onBindViewHolder you have to set your checkbox either checked or unchecked.
if true, your checkbox will be selected, else unselected
holder.checkBox.setChecked(boolean);
You must store your checkbox state. You can do that in your model, for example:
class Model {
String title;
boolean checked;
}
Next you must pass List of Model items to your adapter and check/uncheck checkbox determined by your model.
if (listOfItems.get(position).checked) {
viewHolder.checkbox.setChecked(true);
} else {
viewHolder.checkbox.setChecked(false);
}
Remember that you always need to manage opposite state of views (like checkbox or visibility of view) in adapter.
Try This:
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.RecyclerHolder>
{
private OnClickListener onClickListener;
private int sum =0;
#NonNull
#Override
public RecyclerHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new RecyclerHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_lyt,parent,false));
}
#Override
public void onBindViewHolder(#NonNull RecyclerHolder holder, final int position) {
holder.number.setText(Integer.toString((Integer) alldata.get(position)));
final String text=holder.number.getText().toString();
holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
sum += Integer.parseInt(holder.number.getText().toString());
}else{
sum -= Integer.parseInt(holder.number.getText().toString());
}
if (onClickListener != null) {
onClickListener.onItemClick(sum);
}
});
}
#Override
public int getItemCount() {
return alldata.size();
}
public class RecyclerHolder extends RecyclerView.ViewHolder
{
TextView number;
CheckBox checkBox;
public RecyclerHolder(View itemView) {
super(itemView);
number=itemView.findViewById(R.id.number);
checkBox=itemView.findViewById(R.id.check);
}
}
public void setOnClickListener(OnClickListener onClickListener) {
this.onClickListener = onClickListener;
}
public interface OnClickListener {
void onItemClick(int sum);
}
}
Now In activity use adapter instance like this:
private RecyclerAdapter adapter;
...
...
cardAdapter.setOnClickListener(new CardAdapter.OnClickListener() {
#Override
public void onItemClick(int sum) {
txtSum.setText(String.valueOf(sum));
});
You need to have a field (like "isSelected") in your model class so that all the checked entries can be tracked.you can try following:
checkboxRecyclerView
Basically, RecyclerView recycles the view so you need a model to store the state of the checkbox.
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.RecyclerHolder> {
private List<Model> alldata = new ArrayList<>();
#NonNull
#Override
public RecyclerHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new RecyclerHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_lyt, parent, false));
}
#Override
public void onBindViewHolder(#NonNull RecyclerHolder holder, final int position) {
final Model model = alldata.get(position);
holder.number.setText(String.valueOf(model.value));
holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
model.setChecked(isChecked); // Saves the state of the checkbox.
if (checkeddata != null) {
if (checkeddata.size() == 0) {
checkeddata.add(text);
} else {
if (checkeddata.contains(model.getValue())) {
checkeddata.remove(model.getValue());
} else {
checkeddata.add(model.getValue());
}
}
Iterator iterator = checkeddata.iterator();
int sumnumber = 0;
while (iterator.hasNext()) {
sumnumber = sumnumber + Integer.parseInt((String) iterator.next());
}
sum.setText(Integer.toString(sumnumber));
}
}
});
holder.checkBox.setChecked(model.isChecked()); // Retrieves the state of your checkbox.
}
#Override
public int getItemCount() {
return alldata.size();
}
public class RecyclerHolder extends RecyclerView.ViewHolder {
TextView number;
CheckBox checkBox;
public RecyclerHolder(View itemView) {
super(itemView);
number = itemView.findViewById(R.id.number);
checkBox = itemView.findViewById(R.id.check);
}
}
public void data() {
int g = 1;
for (int i = 10; i <= 500; i++) {
if ((i / 10) == g) {
g = g + 1;
alldata.add(new Model(i));
}
}
}
private class Model {
private int value;
private boolean checked = false;
Model(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
}
}
If you made the necessary changes to store the state of the checkbox, then:
in onBindViewHolder() after final String text=holder.number.getText().toString(); add this:
holder.checkBox.setOnCheckedChangeListener(null);
holder.checkBox.setChecked(-- stored value --);
and then add the listener for the checkbox.

On Scrolling Check Boxes are getting Unchecked or Vice versa in a RecyclerView

I have a check box in RecyclerView Adapter's View Item.
When scrolling, some check boxes are getting checked and some are getting unchecked.
I have taken help from this and this
But I am unable to find the exact solution to this.
Here is my code
public class AllContactsAdapter extends RecyclerView.Adapter<AllContactsAdapter.ViewHolder> {
private Context context;
private ArrayList<PhoneContactsModel> listOfContacts = new ArrayList<>();
PhoneContactsModel phoneContactsModel;
private ArrayList<PhoneContactsModel> copyOfListOfContacts = new ArrayList<>();
public AllContactsAdapter(Context context, ArrayList<PhoneContactsModel> listOfContacts) {
this.context = context;
this.listOfContacts = listOfContacts;
// copyOfListOfContacts.addAll(listOfContacts);
}
#Override
public AllContactsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.
adapter_load_allusers_contacts_listitem, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(final AllContactsAdapter.ViewHolder holder, final int position) {
Log.d("tag", "adapter========3");
phoneContactsModel = listOfContacts.get(position);
holder.name.setText(phoneContactsModel.getContactName());
holder.phoneNumber.setText(phoneContactsModel.getContactNumber());
holder.checkBox.setSelected(phoneContactsModel.isChecked());
holder.contactLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (holder.checkBox.isChecked()) {
phoneContactsModel.setChecked(false);
holder.checkBox.setChecked(false);
copyOfListOfContacts.remove(listOfContacts.get(position));
} else {
phoneContactsModel.setChecked(true);
holder.checkBox.setChecked(true);
copyOfListOfContacts.add(listOfContacts.get(position));
}
}
});
}
#Override
public int getItemCount() {
return listOfContacts.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView name, phoneNumber;
private CheckBox checkBox;
private LinearLayout contactLayout;
public ViewHolder(View view) {
super(view);
name = view.findViewById(R.id.contactNameId);
phoneNumber = view.findViewById(R.id.contactNumberId);
checkBox = view.findViewById(R.id.checkBoxId);
contactLayout = view.findViewById(R.id.contactLayoutId);
}
}
}
For example, I have checked 1,2,3 items in list. When I scrolled down and come up , then 13 is checked and 2 is unchecked along with other some items.Please help me.
Any solution is appreciated.
A simple way arround is do not use OnCheckedChangeListener just set OnClickListener on Check box . Move checkBox onclick inside ViewHolder class.
public class ViewHolder1 extends RecyclerView.ViewHolder implements View.OnClickListener {
CheckBox checkBox;
public ViewHolder1(View itemView) {
super(itemView);
checkBox = (TextView) itemView.findViewById(R.id.checkBox);
checkBox.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(getAdapterPosition()!=-1) {
phoneContactsModel.get(getAdapterPosition()).setChecked(!phoneContactsModel.get(getAdapterPosition()).isChecked());
notifyItemChanged(getAdapterPosition());
}
}
}
And
public void onBindViewHolder(final AllContactsAdapter.ViewHolder holder, final int position) {
holder.checkBox.setChecked(phoneContactsModel.isChecked());
}
notify your adapter.
holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
phoneContactsModel.setChecked(b);
//notifyItemChanged(position);(if you want to notify change in single item)
//or
//notifyDataSetChanged();(if you want to notify change in all)
}
});
no need to use this line of code twice
holder.checkBox.setSelected(phoneContactsModel.isChecked());
//this section seems buggy i assume you want to add the item to the list when ever the check box is checked and remove it from the list when ever the check box is unchecked.
holder.contactLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (phoneContactsModel.isChecked()) {
holder.checkBox.setSelected(false);
copyOfListOfContacts.remove(listOfContacts.get(position));
} else {
holder.checkBox.setSelected(true);
copyOfListOfContacts.add(listOfContacts.get(position));
}
}
}
);
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
final PhoneContactsModel phoneContactsModel = listOfContacts.get(position);
holder.name.setText(phoneContactsModel.getContactName());
holder.phoneNumber.setText(phoneContactsModel.getContactNumber());
holder.checkBox.setChecked(/* gets value from the modal */ phoneContactsModel.isChecked());
holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean value) {
if (compoundButton.isPressed()) {
holder.checkBox.setChecked(value);
// set the value into the modal.
phoneContactsModel.setChecked(value);
if (value) {
copyOfListOfContacts.remove(phoneContactsModel);
} else {
copyOfListOfContacts.add(phoneContactsModel);
}
}
}
});
}
Change your onBindViewHolder method like this. There won't be any unnecessary checks.

Setting up a click listener on a button within a RecycleView

I have it clicked and it gets up to it and shows the right getText() method but the setText method is not working...
userAdapter.setOnEntryClickListener(new UserAdapter.OnEntryClickListener() {
#Override
public void onEntryClick(View view, int position) {
DatabaseUser user = dbUsersList.get(position);
TextView clickedView = (TextView) view.findViewById(R.id.userAdapterFollowBtn);
if(view == clickedView) {
if (clickedView.getText().equals("following")) {
Log.d(Constants.DEBUG, " THE CLICK VIEW IS " + clickedView.getText());
//APPLY Following
String txtFollow = "follow";
clickedView.setText(txtFollow);
if (user.getIsChanged() == 0) {
user.setIsChanged(1);
} else {
user.setIsChanged(0);
}
user.setIsType(3);
db.updateFollow(user);
userAdapter.notifyDataSetChanged();
} else {
clickedView.setText("following");
if (user.getIsChanged() == 0) {
user.setIsChanged(1);
} else {
user.setIsChanged(0);
}
user.setIsType(0);
db.updateFollow(user);
userAdapter.notifyDataSetChanged();
}
} else {
Toast.makeText(getApplicationContext(), user.getUsername() + " is selected!", Toast.LENGTH_SHORT).show();
takeToUserProfile(dbUsersList.get(position));
}
}
});
Here is the adapter class:
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.MyViewHolder> {
private List<DatabaseUser> dbUsersList, followingList;
private DatabaseHelper db;
private Context context;
private Typeface typeFace, italicTypeface, boldTypeface;
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView userAdapterUsername, userAdapterFollowBtn;
public ImageView userAdapterUserPicture;
public MyViewHolder(View view) {
super(view);
userAdapterUsername = (TextView) view.findViewById(R.id.userAdapterUsername);
userAdapterFollowBtn = (TextView) view.findViewById(R.id.userAdapterFollowBtn);
userAdapterUserPicture = (ImageView) view.findViewById(R.id.userAdapterUserPicture);
Log.d(Constants.DEBUG, "IN MY VIEW HOLDER");
view.setOnClickListener(this);
userAdapterFollowBtn.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (mOnEntryClickListener != null) {
Log.d(Constants.DEBUG, "IN On click");
mOnEntryClickListener.onEntryClick(v, getAdapterPosition());
}
}
}
private static OnEntryClickListener mOnEntryClickListener;
public interface OnEntryClickListener {
void onEntryClick(View view, int position);
}
public void setOnEntryClickListener(OnEntryClickListener onEntryClickListener) {
mOnEntryClickListener = onEntryClickListener;
}
public UserAdapter(Context mContext, List<DatabaseUser> usersList, List<DatabaseUser> passedFollowing, Typeface myTypeface, Typeface myTypefaceItalic, Typeface myTypefaceBold) {
context = mContext;
dbUsersList = usersList;
followingList = passedFollowing;
typeFace = myTypeface;
italicTypeface = myTypefaceItalic;
boldTypeface = myTypefaceBold;
Log.d(Constants.DEBUG, "IN MY User ADAPTER CONSTRUCTOR");
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.follow_item, parent, false);
Log.d(Constants.DEBUG, "RETURN ITEM VIEW HOLDER");
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
DatabaseUser user = dbUsersList.get(position);
holder.userAdapterUsername.setTypeface(boldTypeface);
holder.userAdapterUsername.setText(user.getUsername());
final int pos = getItemViewType(position);
//TODO Create pic link
if(containsId(dbUsersList.get(pos), followingList)) {
//Then show following
holder.userAdapterFollowBtn.setText("following");
} else {
//show follow
holder.userAdapterFollowBtn.setText("follow");
}
String userspic = dbUsersList.get(pos).getPicture();
if(userspic == null) {
//SET DEFAULT OR PUT DEFAULT IN XML AND DO NOTHING IT SHOULD SHOW DEFAULT PIC
} else {
//TODO setupUser Pic
String img1 = "http://www.hindustantimes.com/Images/popup/2015/6/kungfu2.jpg";
Picasso.with(context).load(img1).transform(new RoundedTransformation()).into(holder.userAdapterUserPicture);
}
}
#Override
public int getItemCount() {
return dbUsersList.size();
}
public static boolean containsId(DatabaseUser currentUser, List<DatabaseUser> list) {
for (DatabaseUser object : list) {
if (currentUser.getUserId().equals(object.getUserId())) {
return true;
}
}
return false;
}
#Override
public int getItemViewType(int position) {
return position;
}
}
I have done the same in this project, go here and copy this itemclicklistener class:
https://github.com/isaacurbina/MyMovies/blob/c985f28311f25522c7907d090e48dab5fc108c01/app/src/main/java/com/mobileappsco/training/mymovies/Listeners/RecyclerItemClickListener.java
Then on your Activity or Fragment do this with your recyclerview object.
recyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(context, new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
// HERE GOES YOUR CODE FOR THE CLICK OF THE ITEM
}
})
);
Then you can use the position to reference the original object inside the list of objects that your adapter is using (the list should be public so that you can access it from the Activity or Fragment), or do like me and put a hidden textview with the ID instead of the position that you can get with:
TextView clickedItem = (TextView) view.findViewById(R.id.hidden_id_textview);
int id = clickedItem.getText();
You can also check at the whole project that contains the class that I sent you in the link above. I hope it helps.
Kind regards!

Multi selection in RecyclerView

I have list of data with CheckBox. I need to check or uncheck my Check Box from my RecyclerView. When I am trying this more than one check box is selected.
public class AttendanceAdapter extends RecyclerView.Adapter<AttendanceAdapter.MyStudentsViewHolder>{
private LayoutInflater inflater;
private Context contexts;
List<studinformation> data= Collections.emptyList();
public AttendanceAdapter(Context context,List<studinformation> data){
inflater=LayoutInflater.from(context);
this.data=data;
this.contexts=context;
}
#Override
public MyStudentsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= inflater.inflate(R.layout.customrow_students,parent,false);
MyStudentsViewHolder holder=new MyStudentsViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(MyStudentsViewHolder holder, int position) {
studinformation current=data.get(position);
holder.studentid.setText(current.studID);
holder.studentname.setText(current.studName);
holder.studentid.setSelected(true);
}
#Override
public int getItemCount() {
return data.size();
}
class MyStudentsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
CheckBox studentid;
TextView studentname;
public MyStudentsViewHolder(View itemView) {
super(itemView);
studentid= (CheckBox) itemView.findViewById(R.id.ChkSid);
studentname= (TextView) itemView.findViewById(R.id.textName);
studentid.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Toast.makeText(contexts, "Item Clicked At" + getPosition(), Toast.LENGTH_SHORT).show();
if(getPosition()==0) {
// Intent intent = new Intent(contexts, SubActivity.class);
// contexts.startActivity(intent);
}
}
}
}
RecyclerView will reuse the view.so when you return after scrolling it will reset the data it's happening because you are not setting your checkbox selected or not.
In your StudInformation model class create a property isSelected
public class StudInformation
{
private boolean isSelected=false;
public void setSelected(boolean param)
{
this.isSelected=param;
}
public boolean isSelected()
{
return this.isSelected;
}
}
Inside onClick
#Override
public void onClick(View v) {
data.get(getLayoutPosition()).setSelected(studentid.isChecked());
}
In onBindViewHolder
#Override
public void onBindViewHolder(MyStudentsViewHolder holder, int position) {
.....
studinformation current=data.get(position);
holder.studentid.setSelected(current.isSelected());
}
Cross reference link
you have to use setTag() method to get position of each checkbox.
Use this code instead of holder.studentid.setSelected(true); and remove studentid.setOnClickListener(this);
holder.studentid.setChecked(data.get(position).isSelected());
holder.studentid.setTag(data.get(position));
holder.studentid.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
String id = String.valueOf(cb.getTag());
Toast.makeText(
v.getContext(),
"Clicked on Checkbox: " + id, Toast.LENGTH_LONG).show();
}
});

Categories

Resources