RadioButton checked sate automatically changes on scrolling event of RecyclerView - java

I am facing problem with my RadioButton in RecyclerView item. According to the 'type' I changes the checked RadioButton. But after all data loaded, then when I click the non checked radio button it's get checked. But after scrolling the checked radio button which I just clicked that goes unchecked. I want the button which I just clicked to be checked. But it is doesn't stays checked. How do I get what I want? Can anyone please help me!!!!!!!
This is my Adapter Class:
public class AttendanceAdapterLocal extends RecyclerView.Adapter<AttendanceAdapterLocal.ViewHolder>{
private ArrayList<StudentAttendance> attendanceArrayList;
private Context context;
public AttendanceAdapterLocal(ArrayList<StudentAttendance> attendanceArrayList) {
this.attendanceArrayList = attendanceArrayList;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item_mark_attendance, viewGroup, false);
context = viewGroup.getContext();
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder viewHolder, int i) {
final String type = attendanceArrayList.get(i).getType();
final String id = attendanceArrayList.get(i).getId();
final String name = attendanceArrayList.get(i).getName();
final String roll = attendanceArrayList.get(i).getRoll();
viewHolder.setData(name, roll, type, id);
final DatabaseHelper databaseHelper = new DatabaseHelper(context);
final User user = new AccessStorage(context).getUserDetails();
final String userId = user.getUserId();
viewHolder.radioPresent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (databaseHelper.updateStudentAttendanceData(id, userId, "P", "0") > 0) {
Toast.makeText(context, "Marked successfully.", Toast.LENGTH_LONG).show();
viewHolder.radioPresent.setChecked(true);
} else {
Toast.makeText(context, "Unable to mark attendance.", Toast.LENGTH_LONG).show();
}
}
});
viewHolder.radioAbsent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (databaseHelper.updateStudentAttendanceData(id, userId, "A", "0") > 0) {
Toast.makeText(context, "Marked successfully.", Toast.LENGTH_LONG).show();
viewHolder.radioAbsent.setChecked(true);
} else {
Toast.makeText(context, "Unable to mark attendance.", Toast.LENGTH_LONG).show();
}
}
});
viewHolder.radioNone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (databaseHelper.updateStudentAttendanceData(id, userId, "NA", "0") > 0) {
Toast.makeText(context, "Marked successfully.", Toast.LENGTH_LONG).show();
viewHolder.radioNone.setChecked(true);
} else {
Toast.makeText(context, "Unable to mark attendance.", Toast.LENGTH_LONG).show();
}
}
});
}
#Override
public int getItemCount() {
return attendanceArrayList.size();
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
public class ViewHolder extends RecyclerView.ViewHolder {
// Widgets
private TextView textName;
private RadioGroup radioGroup;
private RadioButton radioPresent, radioAbsent, radioNone;
// Vars
private View view;
public ViewHolder(#NonNull View itemView) {
super(itemView);
view = itemView;
textName = view.findViewById(R.id.textName);
radioGroup = view.findViewById(R.id.radioGroup);
radioPresent = view.findViewById(R.id.radioPresent);
radioAbsent = view.findViewById(R.id.radioAbsent);
radioNone = view.findViewById(R.id.radioNone);
}
private void setData(String name, String roll, final String type, final String id) {
textName.setText(roll + ". " + name);
if (type.equals("P")) {
radioPresent.setChecked(true);
} else if(type.equals("A")) {
radioAbsent.setChecked(true);
}else if(type.equals("NA")) {
radioNone.setChecked(true);
}
}
}
}

Just a small mistake . In your onClick method , while changing the state just notify the adapter .
#Override
public void onClick(View v) {
if (databaseHelper.updateStudentAttendanceData(id, userId, "P", "0") > 0) {
Toast.makeText(context, "Marked successfully.", Toast.LENGTH_LONG).show();
viewHolder.radioPresent.setChecked(true);
//Notify adapter
attendanceArrayList.notify();
} else {
Toast.makeText(context, "Unable to mark attendance.", Toast.LENGTH_LONG).show();
}
}
I can see , everywhere you have done the same thing .Its important to notify the adapter while changing anything in the list . You either use notifyDataSetChanged() or notifyItemChanged(selectedPosition);

If you still face the problem you should create a Model class.

Use Interface on click of the radio buttons, make necessary changes in your original list that you are passing in recycler view(Inside Activity) then use notifiDataSetChanged() method.

Related

Trying to save the state of checkbox and the data within that checkbox even when app is closed

I have created a checkbox that can only select one checkbox at a time. This works fine. my app requires the checkbox to remain checked at all times even when app is closed. What i want to know is how to get the checkbox and the data that is stored using this checkbox to save even if my app is closed . I have done some digging and seen that you can use a shared preference but I cant seem to work out how to implement it in my application. here is the code I am currently using to implement the checkbox: firebase recycler adapter
adapter1 = new FirebaseRecyclerAdapter<contact, contactAdapter>(options1) {
#Override
protected void onBindViewHolder(#NonNull final contactAdapter holder, final int position, #NonNull contact model) {
holder.contactName.setText(model.getContactName());
holder.contactPhone.setText(model.getContactPhone());
if(lastCheckedPos == position){
holder.chk.setChecked(true);
}
else{
holder.chk.setChecked(false);
}
holder.chk.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (position == lastCheckedPos) {
holder.chk.setChecked(false);
lastCheckedPos = -1;
}else {
lastCheckedPos = position;
for (int i = 0; i < adapter1.getItemCount(); i++) {
if (adapter1.getItem(i).isSelected(true)) {
number = ((TextView) holder.itemView.findViewById(R.id.contactPhone)).getText().toString();
Toast.makeText(getActivity(), "Data Inserted....." + number, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getActivity(), "Error", Toast.LENGTH_LONG).show();
}
}
contactsView.post(new Runnable()
{
#Override
public void run() {
adapter1.notifyDataSetChanged();
}
});
}
}
});
}
#NonNull
#Override
public contactAdapter onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new contactAdapter(LayoutInflater.from(getActivity()).inflate(R.layout.item_contacts, parent, false));
}
};
Adapter class
public class contactAdapter extends RecyclerView.ViewHolder{
public TextView contactName, contactPhone;
CheckBox chk;
AdapterView.OnItemClickListener itemClickListener;
public contactAdapter(#NonNull View itemView) {
super(itemView);
contactName = itemView.findViewById(R.id.contactName);
contactPhone = itemView.findViewById(R.id.contactPhone);
chk = itemView.findViewById(R.id.myCheckBox);
this.setIsRecyclable(false);
}
}
Any suggestions on how to keep check boxes saved even when my app is closed?
Try to save in shared prefrences the position of the clicked item and the state:
#Override
protected void onBindViewHolder(#NonNull final contactAdapter holder, final int position, #NonNull contact model) {
//setting the views
holder.contactName.setText(model.getContactName());
holder.contactPhone.setText(model.getContactPhone());
//check prefrences for the state of the check
SharedPreferences prefs = getSharedPreferences("check", MODE_PRIVATE);
String check_state = prefs.getString( "state", "default");
if(check_state.equals("true"+String.valueOf(position))){
holder.chk.setChecked(true);
}else if (check_state.equals("false"+String.valueOf(position))){
holder.chk.setChecked(false);
}else{
holder.chk.setChecked(false);
}
//on click save the state in preference
holder.chk.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
//checked
holder.chk.setChecked(true);
//save to prefrences
SharedPreferences.Editor editor = getSharedPreferences("check", MODE_PRIVATE).edit();
editor.putString("state", "true"+String.valueOf(position));
editor.apply();
adapter1.notifyDataSetChanged();
}else {
//unchecked
holder.chk.setChecked(false);
//save to prefrences
SharedPreferences.Editor editor = getSharedPreferences("check", MODE_PRIVATE).edit();
editor.putString("state", "false"+String.valueOf(position));
editor.apply();
adapter1.notifyDataSetChanged();
}
}
});
}

How to update Datamodel in RecyclerviewAdapter

i created a recyclerview where i can see all my chats. Every item contains the name, the lastmessage and a thumb. if the user send or receive a new message, it should be displayed there and the item should go to position 0. Now i have the problem that the message is displayed, but the chat item goes only to the first position if the position was not 0 before. So if i receive two new messages its not working anymore because the data model is the same like before. So how can i fit my data model to the current position of every item. Currently my adapter looks like this:
private static final String TAG = "CustomAdapter";
private Context context;
private Activity mActivity;
private List<MatchesObject> matchesList;
private String currentUid;
public matchadapterino(Activity mActivity, ArrayList<MatchesObject> mDataSet) {
this.mActivity = mActivity;
this.matchesList = mDataSet;
}
// Create new views (invoked by the layout manager)
#Override
public matchadapterino.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view.
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.matchesitem, viewGroup, false);
return new matchadapterino.ViewHolder(v);
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(final matchadapterino.ViewHolder viewHolder, final int position) {
viewHolder.getMatchname().setText(matchesList.get(position).getUsername());
if (!matchesList.get(position).getProfileImageUrl().equals("default")) {
Picasso.with(mActivity).load(matchesList.get(position).getProfileImageUrl()).into(viewHolder.getMatchImage());
getLastMSG(matchesList.get(position).getUserId(), viewHolder.getLastMSG(), position);
viewHolder.getMatchImage().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(mActivity, UserDetailView.class);
//
i.putExtra("userId", matchesList.get(position).getUserId());
mActivity.startActivity(i);
}
});
} else {
viewHolder.getMatchImage().setImageResource(R.mipmap.ic_launcher_round);
}
viewHolder.getForeground().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(mActivity, Chat.class);
Bundle b = new Bundle();
b.putString("matchId", matchesList.get(position).getUserId());
i.putExtras(b);
mActivity.startActivity(i);
}
});
}
#Override
public int getItemCount() {
return matchesList.size();
}
// Get element from your dataset at this position and replace the contents of the view
// with that element
public void removeItem(int position) {
matchesList.remove(matchesList.get(position));
notifyItemRemoved(position);
}
// Return the size of your dataset (invoked by the layout manager)
/**
* Provide a reference to the type of views that you are using (custom ViewHolder)
*/
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView matchname, lastMSG;
public ImageView matchImage;
private RelativeLayout foreground;
private RelativeLayout background;
public ViewHolder(View v) {
super(v);
currentUid = FirebaseAuth.getInstance().getCurrentUser().getUid();
matchname = itemView.findViewById(R.id.matchname);
matchImage = itemView.findViewById(R.id.matchImages);
lastMSG = itemView.findViewById(R.id.lastmsg);
foreground = itemView.findViewById(R.id.foregroundmatch);
background = itemView.findViewById(R.id.backgroundmatch);
}
public RelativeLayout getForeground() {
return foreground;
}
public RelativeLayout getBackground() {
return background;
}
public TextView getLastMSG() {
return lastMSG;
}
public TextView getMatchname() {
return matchname;
}
public ImageView getMatchImage() {
return matchImage;
}
}
private void getLastMSG(final String userId, final TextView lastMSG, final int position) {
final String userid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Users").child(userid).child("connections").child("matches").child(userId);
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
notifyItemMoved(0, position);
Toast.makeText(mActivity, "position changed" + position, Toast.LENGTH_LONG).show();
if (dataSnapshot.child("lastMsgBy").getValue().toString().equals(userid)) {
lastMSG.setTextColor(Color.parseColor("#d2403a3a"));
String lastMsg = dataSnapshot.child("lastMsg").getValue().toString();
lastMSG.setText(lastMsg);
} else {
lastMSG.setTextColor(Color.parseColor("#000000"));
String lastMsg = dataSnapshot.child("lastMsg").getValue().toString();
lastMSG.setText(lastMsg);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}

How can I show toast when all checkboxes in my recyclerview are unchecked?

The closest I can get is to show toast after each checkbox is unchecked, but I want to show toast only after they have all been unchecked. In my onBindViewHolder I have:
((MatchingContact) viewHolder).check.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
// ((MatchingContact) viewHolder).check.setOnClickListener(new CompoundButton.OnClickListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked==false) {
Toast.makeText(context_type, "all unchecked!", Toast.LENGTH_SHORT).show();
}
}
});
Here is my Activity, NewContact.java, code (after request in comment below):
public class NewContact extends AppCompatActivity {
//in this JSONArray, checkedContacts, we will be storing each checkedContact JSON Object
//Then we're going to post it to our NewContact.php file
JSONArray checkedContacts = new JSONArray();
Button phoneContacts;
CheckBox mcheckbox;
//thse are the fields in the xml
private EditText categoryname;
private EditText namename;
private EditText phonename;
private EditText addressname;
private EditText commentname;
int public_or_private;
// ArrayList called selectPhoneContacts that will contain SelectPhoneContact info
ArrayList<SelectPhoneContact> selectPhoneContacts;
ArrayList<String> allPhonesofContacts;
ArrayList<String> allNamesofContacts;
ArrayList<String> MatchingContactsAsArrayList;
String phoneNoofUserCheck;
public String phoneNumberofContact;
String phoneNameofContact;
//For the recycler view, containing the phone contacts
RecyclerView recyclerView;
PopulistoContactsAdapter adapter;
int check_counter = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_contact);
PopulistoContactsAdapter adapter = new PopulistoContactsAdapter(selectPhoneContacts, NewContact.this);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//we are fetching details for the recyclerview - the name, numbers, matching contacts...
LoadContact loadContact = new LoadContact();
loadContact.execute();
//selectPhoneContacts is an empty array list that will hold our SelectPhoneContact info
selectPhoneContacts = new ArrayList<SelectPhoneContact>();
recyclerView = (RecyclerView) findViewById(R.id.rv);
//cast an EditText for each of the field ids in activity_new_contactact.xml
categoryname = (EditText) findViewById(R.id.textViewCategory);
namename = (EditText) findViewById(R.id.textViewName);
phonename = (EditText) findViewById(R.id.textViewPhone);
addressname = (EditText) findViewById(R.id.textViewAddress);
commentname = (EditText) findViewById(R.id.textViewComment);
phoneContacts = (Button) findViewById(R.id.btnPhoneContacts);
phoneContactsButton();
checkboxnull();
public_or_private = 1;
}
// Load data in background
class LoadContact extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... voids) {
//code here to get allPhonesofContacts
allPhonesofContacts = gson.fromJson(json, type);
//code here to get allNamesofContacts
allNamesofContacts = gson.fromJson(jsonNames, type);
System.out.println("NewContact: allNamesofContacts :" + allNamesofContacts);
//code here to get MatchingContactsAsArrayList
MatchingContactsAsArrayList = gsonMatchingContactsAsArrayList.fromJson(jsonMatchingContactsAsArrayList, type1);
System.out.println("SelectPhoneContactAdapter MatchingContactsAsArrayList :" + MatchingContactsAsArrayList);
//for every value in the allPhonesofContacts array list, call it phoneNumberofContact
for (int i = 0; i < allPhonesofContacts.size(); i++) {
phoneNumberofContact = allPhonesofContacts.get(i);
phoneNameofContact = allNamesofContacts.get(i);
SelectPhoneContact selectContact = new SelectPhoneContact();
//if a phone number is in our array of matching contacts
if (MatchingContactsAsArrayList.contains(phoneNumberofContact))
{ //add the selectContacts to the selectPhoneContacts array
// insert the contact at the beginning of the listview
selectPhoneContacts.add(0, selectContact);
//In SelectContact class, so getItemViewType will know which layout to show
selectContact.setType_row("1");
} else {
// insert it at the end (default)
selectPhoneContacts.add(selectContact);
selectContact.setType_row("2");
}
selectContact.setName(phoneNameofContact);
selectContact.setPhone(phoneNumberofContact);
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
PopulistoContactsAdapter adapter = new PopulistoContactsAdapter(selectPhoneContacts, NewContact.this);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager((new LinearLayoutManager(NewContact.this)));
adapter.notifyDataSetChanged();
}
}
#Override
protected void onResume() {
super.onResume();
}
//for the Public Contacts button
private void phoneContactsButton() {
phoneContacts.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
PopulistoContactsAdapter adapter = new PopulistoContactsAdapter(selectPhoneContacts, NewContact.this);
recyclerView.setAdapter(adapter);
// recyclerView.setLayoutManager((new LinearLayoutManager(NewContact.this)));
//loop through the matching contacts
int count = PopulistoContactsAdapter.theContactsList.size();
for (int i = 0; i < count; i++) {
//for contacts that are checked (they can only be matching contacts)...
//PopulistoContactsAdapter.theContactsList.get(i).isSelected=true;
PopulistoContactsAdapter.theContactsList.get(i).setSelected(true);
//we need to notify the recyclerview that changes may have been made
adapter.notifyDataSetChanged();
}
}
});
}
private void checkboxnull() {
//adapter.setOnClickListener(new PopulistoContactsAdapter.OnClickListener() {
PopulistoContactsAdapter adapter = new PopulistoContactsAdapter(selectPhoneContacts, NewContact.this);
adapter.SetOnCheckBoxClickListener(new PopulistoContactsAdapter.OnCheckBoxClickListener() {
#Override
public void onCheckBoxClick(boolean isChecked) {
if (isChecked)
++check_counter;
else
--check_counter;
if (check_counter <= 0)
Toast.makeText(NewContact.this, "all unchecked!", Toast.LENGTH_SHORT).show();
}
});
}
//create a method in your first activity, (where the button color should change):
public void changeColorInFirstActivity(){
// Button btnA = (Button) findViewById(R.id.btnPhoneContacts);
phoneContacts.setBackgroundColor(Color.RED);
}
}
And my Adapter:
public class PopulistoContactsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder > {
private Context mContext;
//make a List containing info about SelectPhoneContact objects
public static List<SelectPhoneContact> theContactsList;
Context context_type;
private OnCheckBoxClickListener onCheckBoxClickListener;
public class MatchingContact extends RecyclerView.ViewHolder {
//In each recycler_blueprint show the items you want to have appearing
public TextView title, phone;
public CheckBox check;
public Button invite;
public MatchingContact(final View itemView) {
super(itemView);
//title is cast to the name id, in recycler_blueprint,
//phone is cast to the id called no etc
title = (TextView) itemView.findViewById(R.id.name);
phone = (TextView) itemView.findViewById(R.id.no);
invite = (Button) itemView.findViewById(R.id.btnInvite);
check = (CheckBox) itemView.findViewById(R.id.checkBoxContact);
}
}
public class nonMatchingContact extends RecyclerView.ViewHolder {
//In each recycler_blueprint show the items you want to have appearing
public TextView title, phone;
public CheckBox check;
public Button invite;
public nonMatchingContact(final View itemView) {
super(itemView);
//title is cast to the name id, in recycler_blueprint,
//phone is cast to the id called no etc
title = (TextView) itemView.findViewById(R.id.name);
phone = (TextView) itemView.findViewById(R.id.no);
invite = (Button) itemView.findViewById(R.id.btnInvite);
check = (CheckBox) itemView.findViewById(R.id.checkBoxContact);
}
}
#Override
public int getItemViewType(int position) {
//for each row in recyclerview, get the getType_row, set in NewContact.java
return Integer.parseInt(theContactsList.get(position).getType_row());
}
public PopulistoContactsAdapter(List<SelectPhoneContact> selectPhoneContacts, Context context) {
//selectPhoneContacts = new ArrayList<SelectPhoneContact>();
theContactsList = selectPhoneContacts;
this.mContext = context;
// whichactivity = activity;
context_type = context;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView;
//if getType_row is 1...
if (viewType == 1)
{
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
itemView = inflater.inflate(R.layout.recycler_blueprint, parent, false);
//itemView.setTag();
return new MatchingContact(itemView);
} else {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
itemView = inflater.inflate(R.layout.recycler_blueprint_non_matching, parent, false);
return new nonMatchingContact(itemView);
}
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, final int position) {
//bind the views into the ViewHolder
//selectPhoneContact is an instance of the SelectPhoneContact class.
//We will assign each row of the recyclerview to contain details of selectPhoneContact:
//The number of rows will match the number of phone contacts
final SelectPhoneContact selectPhoneContact = theContactsList.get(position);
//if the row is a matching contact
if (viewHolder.getItemViewType() == 1)
{
//in the title textbox in the row, put the corresponding name etc...
((MatchingContact) viewHolder).title.setText(selectPhoneContact.getName());
((MatchingContact) viewHolder).phone.setText(selectPhoneContact.getPhone());
((MatchingContact) viewHolder).check.setChecked(theContactsList.get(position).getSelected());
((MatchingContact) viewHolder).check.setTag(position);
((MatchingContact) viewHolder).check.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//pos is the row number that the clicked checkbox exists in
Integer pos = (Integer) ((MatchingContact) viewHolder).check.getTag();
//NEED THIS TO PRESERVE CHECKBOX STATE
//because it is onClick, getSelected will always be the same value
//false or true, it doesn't matter
if (theContactsList.get(pos).getSelected()) {
theContactsList.get(pos).setSelected(false);
Toast.makeText(context_type, theContactsList.get(pos).getPhone() + " clicked!", Toast.LENGTH_SHORT).show();
} else {
theContactsList.get(pos).setSelected(true);
Toast.makeText(context_type, theContactsList.get(pos).getPhone() + " unclicked!", Toast.LENGTH_SHORT).show();
}
}
});
((MatchingContact) viewHolder).check.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
// ((MatchingContact) viewHolder).check.setOnClickListener(new CompoundButton.OnClickListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
onCheckBoxClickListener.onCheckBoxClick(isChecked);
}
});
}
else {
((nonMatchingContact) viewHolder).title.setText(selectPhoneContact.getName());
((nonMatchingContact) viewHolder).phone.setText(selectPhoneContact.getPhone());
}
}
#Override
public int getItemCount() {
return theContactsList.size();
}
public interface OnCheckBoxClickListener {
void onCheckBoxClick(boolean ischecked);
}
public void SetOnCheckBoxClickListener(final OnCheckBoxClickListener onCheckBoxClickListener) {
this.onCheckBoxClickListener = onCheckBoxClickListener;
}
}
Using Interface
Define this interface in your Adapter
private OnCheckBoxClickListener onCheckBoxClickListener;
public interface OnCheckBoxClickListener {
void onCheckBoxClick(boolean ischecked);
}
Add
public void SetOnCheckBoxClickListener(final OnCheckBoxClickListener onCheckBoxClickListener) {
this.onCheckBoxClickListener = onCheckBoxClickListener;
}
Update onBindViewHolder
((MatchingContact) viewHolder).check.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
// ((MatchingContact) viewHolder).check.setOnClickListener(new CompoundButton.OnClickListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
onCheckBoxClickListener.onCheckBoxClick(isChecked);
}
});
in Activity/Fragment
int check_counter = 0;
mAdapter.SetOnCheckBoxClickListener(new YourAdapterClass.OnCheckBoxClickListener() {
#Override
public void onCheckBoxClick(boolean ischecked) {
if (ischecked)
++check_counter;
else
--check_counter;
if (check_counter <= 0)
Toast.makeText(context, "all unchecked!", Toast.LENGTH_SHORT).show();
}
});
You can use a global variable to store the count of the selected checkboxes, and then on each check changed event update the count (add or substruct base on the checked value), and then if the count is 0 after you updated it, all the checkboxes are unchecked
something like that:
//if all the checkboxes are cheked by default
int count = theContactsList.size();
//if all the checkboxes are uncheked by defult
int count = 0;
and
((MatchingContact) viewHolder).check.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
{
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if (!isChecked)
{
count--;
}
else
{
count++;
}
if(count<=0)
{
//all unchcked
}
}
});
I managed to do it with an onClickListener.
In my:
((MatchingContact) viewHolder).check.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
I put:
int count = 0;
int size = theContactsList.size();
for (int i = 0; i < size; i++) {
if (theContactsList.get(i).isSelected) {
count++;
}
}
if(count==0) {
Toast.makeText(context_type, "All unchecked!" , Toast.LENGTH_SHORT).show();
}

Editing a RecyclerView list item with a dialog

I'm building an app that manages the tasks. The user can enter the task name, set priority and add that task. What I want to implement is for the user to be able to click an item, launch an alert dialog and edit the details of that item (name, priority) from that dialog, click "Save Edits" and save the edits for that particular list item. However, the alert dialog does not launch when an item is clicked. I'm trying to call a method containing the dialog through onclick:
recyclerView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
addTaskActivity.onClickEditTask(view);
return true;
}
});
And this is the onClickEditText method:
public class AddTaskActivity extends AppCompatActivity {
...
public void onClickEditTask(View view){
String editedInput = ((EditText)findViewById(R.id.edit_task)).getText().toString();
if(editedInput.length() == 0){
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(getLayoutInflater().inflate(R.layout.edit_dialog, null))
.create();
}
...
}
Currently, I want to know how to launch this method per item click and get the details of that item plastered onto the launched dialog. The following are my relevant classes:
AddTaskActivity.java:
public class AddTaskActivity extends AppCompatActivity {
private int mPriority;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_task);
((RadioButton) findViewById(R.id.radButton1)).setChecked(true);
mPriority = 1;
}
public void onClickAddTask(View view) {
String input = ((EditText) findViewById(R.id.editTextTaskDescription)).getText().toString();
if (input.length() == 0) {
return;
}
ContentValues contentValues = new ContentValues();
contentValues.put(TaskContract.TaskEntry.COLUMN_DESCRIPTION, input);
contentValues.put(TaskContract.TaskEntry.COLUMN_PRIORITY, mPriority);
Uri uri = getContentResolver().insert(TaskContract.TaskEntry.CONTENT_URI, contentValues);
if(uri != null) {
Toast.makeText(getBaseContext(), uri.toString(), Toast.LENGTH_LONG).show();
}
finish();
}
public void onClickEditTask(View view){
String editedInput = ((EditText)findViewById(R.id.edit_task)).getText().toString();
if(editedInput.length() == 0){
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(getLayoutInflater().inflate(R.layout.edit_dialog, null))
.create();
}
public void onPrioritySelected(View view) {
if (((RadioButton) findViewById(R.id.radButton1)).isChecked()) {
mPriority = 1;
} else if (((RadioButton) findViewById(R.id.radButton2)).isChecked()) {
mPriority = 2;
} else if (((RadioButton) findViewById(R.id.radButton3)).isChecked()) {
mPriority = 3;
}
}
}
MainActivity.java:
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int LOADER_ID = 0;
private CustomCursorAdapter customCursorAdapter;
RecyclerView recyclerView;
private AddTaskActivity addTaskActivity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recyclerViewTasks);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
customCursorAdapter = new CustomCursorAdapter(this);
recyclerView.setAdapter(customCursorAdapter);
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
int id = (int) viewHolder.itemView.getTag();
String itemId = Integer.toString(id);
Uri uri = TaskContract.TaskEntry.CONTENT_URI;
uri = uri.buildUpon().appendPath(itemId).build();
getContentResolver().delete(uri, null, null);
getSupportLoaderManager().restartLoader(LOADER_ID, null, MainActivity.this);
}
}).attachToRecyclerView(recyclerView);
recyclerView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
addTaskActivity.onClickEditTask(view);
return true;
}
});
FloatingActionButton floatingActionButton = (FloatingActionButton) findViewById(R.id.fab_btn);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent addTaskIntent = new Intent(MainActivity.this, AddTaskActivity.class);
startActivity(addTaskIntent);
}
});
getSupportLoaderManager().initLoader(LOADER_ID, null, this);
}
#Override
protected void onResume() {
super.onResume();
getSupportLoaderManager().restartLoader(LOADER_ID, null, this);
}
#Override
public Loader<Cursor> onCreateLoader(int id, final Bundle loaderArgs) {
return new AsyncTaskLoader<Cursor>(this) {
Cursor cursor = null;
#Override
protected void onStartLoading() {
if (cursor != null) {
deliverResult(cursor);
} else {
forceLoad();
}
}
#Override
public Cursor loadInBackground() {
try {
return getContentResolver().query(TaskContract.TaskEntry.CONTENT_URI,
null,
null,
null,
TaskContract.TaskEntry.COLUMN_PRIORITY);
} catch (Exception e) {
Log.e(TAG, "Failed to load data.");
e.printStackTrace();
return null;
}
}
public void deliverResult(Cursor data) {
cursor = data;
super.deliverResult(data);
}
};
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
customCursorAdapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
customCursorAdapter.swapCursor(null);
}
}
CustomCursorAdapter.java:
public class CustomCursorAdapter extends RecyclerView.Adapter<CustomCursorAdapter.TaskViewHolder> {
private Cursor cursor;
private Context con;
public CustomCursorAdapter(Context context) {
this.con = context;
}
#Override
public TaskViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(con).inflate(R.layout.task_layout, parent, false);
return new TaskViewHolder(view);
}
#Override
public void onBindViewHolder(TaskViewHolder holder, int position) {
int index = cursor.getColumnIndex(TaskContract.TaskEntry._ID);
int descriptionOfIndex = cursor.getColumnIndex(TaskContract.TaskEntry.COLUMN_DESCRIPTION);
int priorityofIndex = cursor.getColumnIndex(TaskContract.TaskEntry.COLUMN_PRIORITY);
cursor.moveToPosition(position);
final int id = cursor.getInt(index);
String description = cursor.getString(descriptionOfIndex);
int priority = cursor.getInt(priorityofIndex);
holder.itemView.setTag(id);
holder.taskDescriptionView.setText(description);
String priorityString = "" + priority;
holder.priorityView.setText(priorityString);
GradientDrawable priorityCircle = (GradientDrawable) holder.priorityView.getBackground();
int priorityColor = getPriorityColor(priority);
priorityCircle.setColor(priorityColor);
}
private int getPriorityColor(int priority) {
int priorityColor = 0;
switch(priority) {
case 1: priorityColor = ContextCompat.getColor(con, R.color.materialRed);
break;
case 2: priorityColor = ContextCompat.getColor(con, R.color.materialOrange);
break;
case 3: priorityColor = ContextCompat.getColor(con, R.color.materialYellow);
break;
default: break;
}
return priorityColor;
}
#Override
public int getItemCount() {
if (cursor == null) {
return 0;
}
return cursor.getCount();
}
public Cursor swapCursor(Cursor c) {
if (cursor == c) {
return null;
}
Cursor temp = cursor;
this.cursor = c;
if (c != null) {
this.notifyDataSetChanged();
}
return temp;
}
class TaskViewHolder extends RecyclerView.ViewHolder {
TextView taskDescriptionView;
TextView priorityView;
public TaskViewHolder(View itemView) {
super(itemView);
taskDescriptionView = (TextView) itemView.findViewById(R.id.taskDescription);
priorityView = (TextView) itemView.findViewById(R.id.priorityTextView);
}
}
}
You appear to have omitted showing the alter dialog by coding builder.show();
Additionally may want to setup some buttons (you can use Neutral, Positive and Negative buttons, below is example with just Neutral button).
You probably want to set the title and make the AlertDialog cancelable.
You may also have an issue with the custom layout, so the code below will ignore that and use the default layout.
I believe that the following code will fix this issue:-
public void onClickEditTask(View view){
String editedInput = ((EditText)findViewById(R.id.edit_task)).getText().toString();
if(editedInput.length() == 0){
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Test");
builder.setCancelable(true);
builder.setNeutralButton("TEST", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Log.d("TAG","You click the TEST button of the dialog.");
}
});
builder.show();
}
Introducing a custom layout
The following is the above but with an added rudimentary custom view, first the layout, namely test_hi.xml :-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/buildertv"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_marginTop="30dp"
android:layout_marginStart="30dp"
android:layout_marginLeft="30dp"
android:text="TEST"
android:textColor="#ff557799"
android:gravity="center"
>
</TextView>
</LinearLayout>
And the code (i.e. with builder.setView(R.layout.test_hi); added) :-
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(R.layout.test_hi);
builder.setTitle("Test");
builder.setCancelable(true);
builder.setNeutralButton("TEST", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Log.d("TAG","You clicked the TEST button of the dialog.");
}
});
builder.show();
Running the above should be something like (*running the previous code will not have the middle *Test**):-
Clicking the bottom (Red) Test will add a line to the log along the lines of:-
....D/TAG: You clicked the TEST button of the dialog.
You would replace Log.d("TAG","You clicked the TEST button of the dialog."); with the code that you want to run when the Neutral Button is clicked. If you wanted other options then you can use the Positive and Negative buttons in a similar way by adding builder.setPositiveButton(.... and builder.setNegativeButton(.... accordingly.

Saving the state of a single spinner with different uses

Please i have a spinner in a CustomAdapterClass which extends ArrayAdapter. I want to save the state of the spinner even when the activity is destroyed. It is only one spinner that appears in a listview. I have searched but all i see is when there are more than one spinner, each having it's own id. How do i achieve this please. Here is my code
public class CustomListAdapterForCgpa extends ArrayAdapter<String> implements AdapterView.OnItemSelectedListener {
LinearLayout colorLayout;
TextView userGpScoreUneditable;
Spinner spinnerForGradePoints;
public String mathSubject= "Mathematics";
public String chemSubject = "Chemistry";
public String physicsSubject = "Physics";
public String biologySubject = "Biology";
public String gsSubject = "General Studies";
public String cscSubject = "CSC";
SharedPreferences sharedPreferences;
SharedPreferences.Editor editor;
public CustomListAdapterForCgpa(Context context, ArrayList<String> subjects) {
super(context, R.layout.custom_list_view_cgpa, subjects);
}
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
#NonNull
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
View customView = layoutInflater.inflate( R.layout.custom_list_view_cgpa,parent,false);
String singleSubject = getItem(position);
TextView singleText = (TextView) customView.findViewById(R.id.listSubjectsMyCoursesCgpa);
colorLayout = (LinearLayout)customView.findViewById(R.id.colorForSubjectsCgpa);
userGpScoreUneditable = (TextView)customView.findViewById(R.id.userGpScoreUneditable);
spinnerForGradePoints = (Spinner)customView.findViewById(R.id.spinnerForGradePointCgpa);
ArrayAdapter<String> gradePointAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_dropdown_item, TabFirstSemesterMyCGPA.userSubjectGrade);
spinnerForGradePoints.setAdapter(gradePointAdapter);
spinnerForGradePoints.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
String selectedItem = adapterView.getItemAtPosition(i).toString();
if (selectedItem.equals("A"))
{
Toast.makeText(getContext(), "You Clicked A", Toast.LENGTH_SHORT).show();
}else if ( selectedItem.equals("B"))
{
Toast.makeText(getContext(), "You Clicked B", Toast.LENGTH_SHORT).show();
}else if ( selectedItem.equals("C"))
{
Toast.makeText(getContext(), "You Clicked C", Toast.LENGTH_SHORT).show();
}else if ( selectedItem.equals("D"))
{
Toast.makeText(getContext(), "You Clicked D", Toast.LENGTH_SHORT).show();
}else if ( selectedItem.equals("E"))
{
Toast.makeText(getContext(), "You Clicked E", Toast.LENGTH_SHORT).show();
}else if ( selectedItem.equals("F"))
{
Toast.makeText(getContext(), "You Clicked F", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
singleText.setText(singleSubject);
colorLayout.setBackgroundColor(UserCourseSelection2.userSubjectsListColor.get(position));
return customView;
}
}
In pure Java you could save the state as a static field. The value will persist after the activity is destroyed because it belongs to the Class, not an instance. It should work the same in Android.

Categories