Adapter not attached, layout skipped - java

my java LogCat has this error:
E/RecyclerView: No adapter attached; skipping layout.
I tried all the solutions online but to no avail. When I click on a button in the recyclerview(list item) this Error will appear and my header do not change according to the database set. My database is working fine. can someone help me with this? I need to get this done in five days. Your help would be greatly appreciated.
public class contactsPage extends AppCompatActivity {
RecyclerView recyclerView;
AdapterUsers adapterUsers;
DatabaseReference ref;
FirebaseDatabase database;
List<ModelUser>userList;
FirebaseAuth firebaseAuth;
private void checkUserStatus() {
//get current user
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
}
else {
startActivity(new Intent(this, login.class));
finish();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contacts_page);
recyclerView = findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
//init user list
userList = new ArrayList<>();
//getall user
getAllUsers();
}
private void getAllUsers () {
//get current user
final FirebaseUser fUser = FirebaseAuth.getInstance().getCurrentUser();
//get path of database named users
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users");
//get all data from path
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
userList.clear();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
ModelUser modelUser = ds.getValue(ModelUser.class);
//get all users except currently signed in user
if (!modelUser.getEmail().equals(fUser.getEmail())) {
userList.add(modelUser);
}
//adapter
adapterUsers = new AdapterUsers(contactsPage.this, userList);
//set adapter to recycler view
recyclerView.setAdapter(adapterUsers);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
My adapter class are as follow:
package com.example.black.adapters;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.example.whereareu.ChatActivity;
import com.example.whereareu.R;
import com.example.whereareu.models.ModelUser;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
public class AdapterUsers extends RecyclerView.Adapter<AdapterUsers.MyHolder>{
Context context;
List<ModelUser> userList;
//constructor
public AdapterUsers(Context context, List<ModelUser> userList) {
this.context = context;
this.userList = userList;
}
#NonNull
#Override
public MyHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//inflate layout(row_users.xml)
View view = LayoutInflater.from(context).inflate(R.layout.row_users, parent, false);
return new MyHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyHolder holder, int position) {
//get data
final String hisUID = userList.get(position).getUid();
final String userName = userList.get(position).getName();
String userEmail = userList.get(position).getEmail();
//set data
holder.userName.setText(userName);
holder.userEmail.setText(userEmail);
//handle item click
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, ChatActivity.class);
intent.putExtra("hisUID", hisUID);
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return userList.size();
}
//view holder class
class MyHolder extends RecyclerView.ViewHolder{
TextView userName, userEmail;
public MyHolder(#NonNull View itemView) {
super(itemView);
//init views
userName = itemView.findViewById(R.id.userName);
userEmail = itemView.findViewById(R.id.userEmail);
}
}
}

Try to write adapter codes out of the for-loop.
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
userList.clear();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
ModelUser modelUser = ds.getValue(ModelUser.class);
//get all users except currently signed in user
if (!modelUser.getEmail().equals(fUser.getEmail())) {
userList.add(modelUser);
}
}
//adapter
adapterUsers = new AdapterUsers(contactsPage.this, userList);
//set adapter to recycler view
recyclerView.setAdapter(adapterUsers);
}

You are setting the adapter only when the data is finished loading in the background.
You need to call recyclerView.setAdapter(yourAdapter) before the layout finishes loading. I suggest you do something like:
public class ContactsPageActivity extends AppCompatActivity {
// ...
AdapterUsers adapterUsers = new AdapterUsers(this);
List<ModelUser> userList = = new ArrayList<>();
// ...
#Override
protected void onCreate(Bundle savedInstanceState) {
// ...
recyclerView = findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapterUsers);
getAllUsers();
}
private void getAllUsers () {
// ...
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
// ...
adapterUsers.update(userList); // You need to create this method in your adapter. Call "notifyDatasetChanged" in it.
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
Also it needs to be out of the loop, like #Sinan Dönmez said

Related

error E/RecyclerView: No adapter attached; skipping layout when setting a firebase recyclerview android studio [duplicate]

This question already has answers here:
Firebase:Recycler view No Adater attached , Skipping Layout
(3 answers)
Closed 2 years ago.
i got an eror in my recyclerview code, this is just a simple code that retrieve a child from uid database but it doesn't show anything and i get this E/RecyclerView: No adapter attached; skipping layout error in my logcat
here's my MainActivity
public class ProsesPesananActivity extends AppCompatActivity {
DatabaseReference database;
RecyclerView recyclerView;
ArrayList<Status> list;
StatusAdapter adapter;
String uid;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_proses_pesanan);
final FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
uid = firebaseAuth.getUid();
recyclerView = (RecyclerView) findViewById(R.id.list_proses);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
list = new ArrayList<Status>();
database = FirebaseDatabase.getInstance().getReference().child("PasFoto").child(uid);
database.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren())
{
Status s = dataSnapshot.getValue(Status.class);
list.add(s);
}
adapter = new StatusAdapter(ProsesPesananActivity.this,list);
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(ProsesPesananActivity.this, "Error", Toast.LENGTH_SHORT).show();
}
});
}
}
here's my Adapter
public class StatusAdapter extends RecyclerView.Adapter<StatusAdapter.MyViewHolder> {
Context context;
ArrayList<Status> statuses;
public StatusAdapter (Context c, ArrayList<Status> s){
context = c;
statuses = s;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item_status,parent,false));
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.shopId.setText(statuses.get(position).getShopId());
}
#Override
public int getItemCount() {
return statuses.size();
}
class MyViewHolder extends RecyclerView.ViewHolder
{
TextView shopId, ukuran, jumlah, total, status;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
shopId = (TextView) itemView.findViewById(R.id.tv_shopId);
ukuran = (TextView) itemView.findViewById(R.id.tv_ukuran);
jumlah= (TextView) itemView.findViewById(R.id.tvDetailJumlah);
total = (TextView) itemView.findViewById(R.id.tv_total);
}
}
}
as you can see i tried to retrive the data from firebase into my recyclerview using card layout, but i got nothing instead
The error saying no adapter attached means just that. It probably caused by ValueEventListener.onDataChange() never get called.
Nevertheless, a better practice would be setting the adapter beforehand and notify the adapter of any changes made. Whatever your intention is, make sure that ValueEventListener.onDataChange() gets called at least once, or else it might not work the way you originally wanted. In that case, try to study the actual ValueEventListener usage.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* ... your code ... */
list = new ArrayList<Status>();
adapter = StatusAdapter(this, list);
// Edit: Set adapter to RecyclerView`
recyclerView = (RecyclerView) findViewById(R.id.list_proses);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
database = FirebaseDatabase.getInstance().getReference().child("PasFoto").child(uid);
database.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren())
{
Status s = dataSnapshot.getValue(Status.class);
list.add(s);
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(ProsesPesananActivity.this, "Error", Toast.LENGTH_SHORT).show();
}
});
}
Additionally, Jetpack Paging library is highly recommended in dealing with RecyclerView as it can conserve data & memory usage although the implementation steps are a bit not-really-straight-forward, but sure is fun once you get the hang of it.

Remove RecyclerView Firebase Item Android Java

I've created a favourites page using a RecyclerView with data saved on firebase. I'm attempting to delete an item from both firebase and the recyclerview in realtime. I can remove the item using
dataSnapshot.child(countries.get(position).getId()).getRef().removeValue();
countries.remove(position);
However, I can't remove the last item, but it deletes in firebase. I've tried different combinations of
notifyDataSetChanged();
notifyItemRemoved(position);
notifyItemRangeChanged(position, countries.size());
But with no luck so far, I can't see where I'm going wrong.
Populating recyclerview
Public class FavouritesFragment extends Fragment {
RecyclerView recyclerView;
RecyclerView.LayoutManager layoutManager;
RecyclerView.Adapter adapter;
ArrayList<Country> countries;
private FirebaseAuth firebaseAuth;
private DatabaseReference databaseReference;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_favourites, container, false);
getActivity().setTitle("Favourites");
firebaseAuth = FirebaseAuth.getInstance();
databaseReference = FirebaseDatabase.getInstance().getReference();
FirebaseUser user = firebaseAuth.getCurrentUser();
String userID = user.getUid();
databaseReference = databaseReference.child("users").child(userID).child("Favourites");
recyclerView = view.findViewById(R.id.favourites_recycler);
countries = new ArrayList<>();
layoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
addFavourites();
return view;
}
public void addFavourites(){
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds: dataSnapshot.getChildren()){
Country c = ds.getValue(Country.class);
countries.add(c);
}
adapter = new FavouritesAdapter(countries);
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
Deleting from RecyclerView in adapter class
public class FavouritesAdapter extends RecyclerView.Adapter<FavouritesAdapter.MyViewHolder>{
ArrayList<Country> countries;
private View view;
ImageBindingAdapter imageBindingAdapter = new ImageBindingAdapter();
RecyclerView recyclerView;
private int position;
private FirebaseDatabase firebaseDatabase;
private FirebaseAuth firebaseAuth;
private DatabaseReference databaseReference;
public FavouritesAdapter(ArrayList<Country> countries1){
countries = countries1;
}
#NonNull
#Override
public FavouritesAdapter.MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.favourites, viewGroup, false);
recyclerView = view.findViewById(R.id.favourites_recycler);
firebaseAuth = FirebaseAuth.getInstance();
firebaseDatabase = FirebaseDatabase.getInstance();
databaseReference = firebaseDatabase.getReference();
FirebaseUser user = firebaseAuth.getCurrentUser();
String userID = user.getUid();
databaseReference = databaseReference.child("users").child(userID).child("Favourites");
return new FavouritesAdapter.MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final FavouritesAdapter.MyViewHolder myViewHolder, final int i) {
myViewHolder.name.setText(countries.get(i).getName());
myViewHolder.snippet.setText(countries.get(i).getSnippet());
myViewHolder.popUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
PopupMenu popup = new PopupMenu(view.getContext(), view);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.popup_menu, popup.getMenu());
popup.show();
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.add_to_favs:
deleteFavourite();
break;
default:
return false;
}
return true;
}
});
}
});
#Override
public int getItemCount() {
return countries.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
public TextView name;
public ImageView popUp;
public MyViewHolder(View itemView) {
super(itemView);
name = itemView.findViewById(R.id.cityName);
popUp = itemView.findViewById(R.id.dotsPopUp);
}
}
public void deleteFavourite(){
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String id = countries.get(position).getId();
if(dataSnapshot.exists() && dataSnapshot.child(id).exists()){
dataSnapshot.child(countries.get(position).getId()).getRef().removeValue();
countries.remove(position);
// notifyDataSetChanged();
// notifyItemRemoved(position);
// notifyItemRangeChanged(position, countries.size());
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
}); }
}
In your adapter you didn't set the position to the position of the item you need to delete. So when the user hits the delete item in the popUp menu, you call deleteFavourite();, but you need to set the class field position before calling deleteFavourite().
So, in onBindViewHolder, you need to assign the value of the second parameter to the position, and it's better to pass it to deleteFavourite() method as a paraemter like deleteFavourite(position):
#Override
public void onBindViewHolder(#NonNull final FavouritesAdapter.MyViewHolder myViewHolder, final int pos) {
....
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.add_to_favs:
deleteFavourite(pos);
break;
default:
return false;
}
return true;
}
});
Then change your deleteFavourite to accept the new parameter, and notifyItemRemoved(position);
public void deleteFavourite(int pos){
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String id = countries.get(pos).getId();
if(dataSnapshot.exists() && dataSnapshot.child(id).exists()){
dataSnapshot.child(countries.get(pos).getId()).getRef().removeValue();
countries.remove(pos);
notifyItemRemoved(pos);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
Do this to remove object from list, in deleteFavourite() function:
..........
if(dataSnapshot.exists() && dataSnapshot.child(id).exists()){
dataSnapshot.child(countries.get(position).getId()).getRef().removeValue();
countries.remove(countries.get(position));
notifyDataSetChanged();
}
..............

How to remove item from firebase list

I use firebase database and recycler view.
I add a list of items to firebase using the push (); command.
While using push(); , firebase creating a unique id for each added item.
Now, i want delete item on click delete button, but when i try removeValue(); function to my DB ref, it delete the all repository and not just the item.
That what i have now:
Fragment that read data from firebase
users.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull final DataSnapshot dataSnapshot) {
notes.clear();
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
note = dataSnapshot1.getValue(Note.class);
notes.add(note);
}
adapter = new NotesAdapter(notes, getActivity());
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(), 3);
RVNotesList.setLayoutManager(layoutManager);
RVNotesList.setAdapter(adapter);
adapter.setOnNoteClickListener(new NotesAdapter.OnNoteClickListener() {
#Override
public void onNoteClick(final int position) {
users.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
//TODO delete pressed item.
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
My onClick buttons
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.saveNoteBTN:
String title = ETnoteTitle.getText().toString().trim();
String desc = ETnoteDesc.getText().toString().trim();
String date = ETnoteLastDate.getText().toString().trim();
if (title.isEmpty() || desc.isEmpty() || date.isEmpty()) {
return;
}
note = new Note(title, desc, date);
users.push().setValue(note).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d("NoteAdded", "true");
getFragmentManager().beginTransaction().
remove(getFragmentManager().findFragmentById(R.id.bottom_container)).commit();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d("NoteAdded", "false");
}
});
break;
case R.id.deleteNoteBTN:
getFragmentManager().beginTransaction().
remove(getFragmentManager().findFragmentById(R.id.bottom_container)).commit();
break;
}
}
Adapter
package com.enjoyapp.eventmanagement.Adapters;
import android.app.Dialog;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import com.enjoyapp.eventmanagement.Models.Note;
import com.enjoyapp.eventmanagement.R;
import java.util.ArrayList;
public class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.NotesViewHolder> {
private ArrayList<Note> notes;
private Context context;
private OnNoteClickListener onNoteClickListener;
public NotesAdapter(ArrayList<Note> notes, Context context) {
this.notes = notes;
this.context = context;
}
public interface OnNoteClickListener {
void onNoteClick(int position);
}
public void setOnNoteClickListener(OnNoteClickListener onNoteClickListener) {
this.onNoteClickListener = onNoteClickListener;
}
#NonNull
#Override
public NotesViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.note_list_item, parent, false);
return new NotesAdapter.NotesViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final NotesViewHolder holder, final int position) {
final Note note = notes.get(position);
holder.mNoteTitle.setText(notes.get(position).getmTitle());
holder.mNoteDesc.setText(notes.get(position).getmDescription());
String lastDayToConfirmNote = (notes.get(position).getmDay() + "/"
+ notes.get(position).getmMonth() + "/" + notes.get(position).getmYear());
holder.mLastDay.setText(lastDayToConfirmNote);
#Override
public int getItemCount() {
return notes.size();
}
public class NotesViewHolder extends RecyclerView.ViewHolder {
private TextView mNoteTitle;
private TextView mNoteDesc;
private TextView mLastDay;
private CardView note_card;
public NotesViewHolder(#NonNull View itemView) {
super(itemView);
mNoteTitle = itemView.findViewById(R.id.note_title);
mNoteDesc = itemView.findViewById(R.id.note_description);
mLastDay = itemView.findViewById(R.id.note_last_date);
note_card = itemView.findViewById(R.id.note_card);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (onNoteClickListener!=null){
onNoteClickListener.onNoteClick(getAdapterPosition());
}
}
});
}
}
public void removeItem(ArrayList arrayList, int position) {
arrayList.remove(arrayList.get(position));
notifyItemRemoved(position);
notifyItemRangeChanged(position, arrayList.size());
}
}
According to your code, it seems that users is your parent root and you want to delete one of the child of users. For that, you will need the id of that child. You can get id and save it in ArrayList like
ArrayList<String> ids = new ArrayList
users.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull final DataSnapshot dataSnapshot) {
notes.clear();
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
note = dataSnapshot1.getValue(Note.class);
notes.add(note);
ids.add(dataSnapshot1.getKey());//saving id of each child
}
adapter = new NotesAdapter(notes, getActivity());
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(), 3);
RVNotesList.setLayoutManager(layoutManager);
RVNotesList.setAdapter(adapter);
adapter.setOnNoteClickListener(new NotesAdapter.OnNoteClickListener() {
#Override
public void onNoteClick(final int position) {
users.child(ids.get(position)).removeValue();
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
NOTE : You have to update ids arraylist when you will update notes arraylist.

Can't convert object of type java.lang.String to type (Firebase,RecyclerView)

I got two RecyclerView on the same page at this moments which are Breakfast and Lunch RecyclerView but I am facing the following error Can't convert object of type java.lang.String to type com.example
It highlights this line
userRecordslist.add(ds.getValue(UserRecordsModel.class));
I have tried several ways.
but when I used this code , the data from different record was displayed in the Breakfast RecyclerView
myRef = FirebaseDatabase.getInstance().
getReference("UsersRecords").child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.child(date_record);
these are the screenshots of my Firebase and my App. You can see both data from different record is displayed on the same RecyclerView.
and later I tried to use this "new" code for database reference, the data that was supposedly retrieved from Firebase was NOT be displayed on the Breakfast Recycler View and I got the Can't convert object of type java.lang.String to type error
myRef = FirebaseDatabase.getInstance().
getReference("UsersRecords").child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.child(date_record).child("BreakfastRecord");
I want to fetch the data and display it in the "suppose" RecyclerView. Please help out.
This code for my PlanMeal activity:
//BUTTON
Button backBtn;
Button addMealBreakBtn;
Button addMealLunchBtn;
Button addMealDinnerBtn;
//DATABASE
FirebaseAuth mAuth;
FirebaseUser currentUser;
DatabaseReference userRecordRef, myRef,requiredCalorieRef, mylunchRef;
//TEXT VIEW
TextView userRequiredCalorie;
ArrayList<UserRecordsModel> userRecordslist;
RecyclerView recyclerView, recyclerViewlunch;
private RecyclerView.Adapter userRecordHolder;
//DATE
String date_record ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_plan_meal_user);
date_record = new SimpleDateFormat("yyMMdd", Locale.getDefault()).format(new Date());
//create a date string.
String date_n = new SimpleDateFormat("MMM dd, yyyy", Locale.getDefault()).format(new Date());
//get hold of textview.
TextView date = (TextView) findViewById(R.id.datePlanMeal);
//set it as current date.
date.setText(date_n);
//INI VIEWS
userRequiredCalorie= (TextView) findViewById(R.id.outputPlanMealCalorie);
//FIREBASE AUTH
mAuth = FirebaseAuth.getInstance();
currentUser=mAuth.getCurrentUser();
//DATABASE REFERENCE
myRef = FirebaseDatabase.getInstance().
getReference("UsersRecords").child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.child(date_record);
/*mylunchRef=FirebaseDatabase.getInstance().
getReference("UsersRecords").child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.child(date_record).child("LunchRecord");*/
//myRef = FirebaseDatabase.getInstance().getReference("UsersRecords").child(FirebaseAuth.getInstance().getCurrentUser().getUid());
//mylunchRef = FirebaseDatabase.getInstance().getReference("UsersRecords").child(FirebaseAuth.getInstance().getCurrentUser().getUid());
//RECYCLER VIEW
//*********BREAKFAST******************************************//
recyclerView = findViewById(R.id.userRecordRecylerView);
LinearLayoutManager manager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(manager);
recyclerView.setHasFixedSize(true);
//ADAPTER
userRecordslist = new ArrayList<>();
userRecordHolder = new UserRecordsHolder(userRecordslist);
recyclerView.setAdapter(userRecordHolder);
//*********LUNCH******************************************//
recyclerViewlunch = findViewById(R.id.userRecordRecylerViewLunch);
LinearLayoutManager manager1 = new LinearLayoutManager(this);
recyclerViewlunch.setLayoutManager(manager1);
recyclerViewlunch.setHasFixedSize(true);
//ADAPTER
userRecordslist = new ArrayList<>();
userRecordHolder = new UserRecordsHolder(userRecordslist);
recyclerViewlunch.setAdapter(userRecordHolder);
//BUTTON
addMealBreakBtn = (Button) findViewById(R.id.addMealBreakBtn);
backBtn = (Button)findViewById(R.id.backBtnPlan) ;
//**********************DATABASE REFERENCE FOR USER REQUIRED CALORIE***************************//
requiredCalorieRef = FirebaseDatabase.getInstance().getReference("Users").child(FirebaseAuth.getInstance().getCurrentUser().getUid());
requiredCalorieRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String userCalorieSuggestion = String.valueOf((dataSnapshot.child("daily calorie").getValue()));
userRequiredCalorie.setText((userCalorieSuggestion +"kcal"));
/*String userCalorieSuggestion = Double.toString((Double) dataSnapshot.child("daily calorie").getValue());
showDailyCalorie.setText(("Daily Calorie Suggestion: " + userCalorieSuggestion +"kcal"));*/
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
//BACK BUTTON*************************************************
backBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent signIn = new Intent(PlanMealUser.this,HomepageUser.class);
startActivity(signIn);
}
});
//ADD MEAL BUTTONS**********************************************
addMealBreakBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent breakfast = new Intent(PlanMealUser.this,ViewProduct.class);
startActivity(breakfast);
}
});
addMealLunchBtn = (Button) findViewById(R.id.addMealLunchBtn);
addMealLunchBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent signIn = new Intent(PlanMealUser.this,ViewProduct_Lunch.class);
startActivity(signIn);
}
});
addMealDinnerBtn = (Button) findViewById(R.id.addMealDinnerBtn);
addMealDinnerBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent signIn = new Intent(PlanMealUser.this,ViewProduct.class);
startActivity(signIn);
}
});
}
#Override
protected void onStart() {
super.onStart();
if (myRef != null) {
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
userRecordslist = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
userRecordslist.add(ds.getValue(UserRecordsModel.class));
}
UserRecordsHolder userRecordHolder = new UserRecordsHolder(userRecordslist);
recyclerView.setAdapter(userRecordHolder);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(PlanMealUser.this, databaseError.getMessage(),
Toast.LENGTH_SHORT).show();
}
});
}
}
}
This is my Model :
package com.example.buddymealplanneruser.Child.UserRecords;
public class UserRecordsModel {
private String foodName;
private String foodCalorie;
//constructor
public UserRecordsModel (String foodName,
String foodCalorie
)
{
this.foodName = foodName;
this.foodCalorie = foodCalorie;
}
public UserRecordsModel(){
}
//Getter and Setter
public String getFoodName() {
return foodName;
}
public void setFoodName(String foodName) {
this.foodName = foodName;
}
public String getFoodCalorie() {
return foodCalorie;
}
public void setFoodCalorie(String foodCalorie) {
this.foodCalorie = foodCalorie;
}
}
This is my Adapter
public class UserRecordsHolder extends RecyclerView.Adapter<UserRecordsHolder.MyURHolder> {
Context context;
ArrayList<UserRecordsModel> userRecordslist;
public UserRecordsHolder (ArrayList<UserRecordsModel> userRecordslist)
{
this.userRecordslist=userRecordslist;
}
#NonNull
#Override
public MyURHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_user_records, viewGroup,false);
return new MyURHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyURHolder myURHolder, int i) {
myURHolder.foodName.setText(userRecordslist.get(i).getFoodName());
myURHolder.foodCalorie.setText(userRecordslist.get(i).getFoodCalorie());
}
#Override
public int getItemCount()
{
return userRecordslist.size();
}
class MyURHolder extends RecyclerView.ViewHolder
{
TextView foodName, foodCalorie;
public MyURHolder (#NonNull View itemView){
super(itemView);
foodName = itemView.findViewById(R.id.userRecordsFName);
foodCalorie = itemView.findViewById(R.id.userRecordsKcal);
}
}
}
Hope someone can help.
You'll need one more level beneath BreakfastRecord or LunchRecord:
UserRecords
UID
Date
BreakfastRecord
1
foodCalorie
foodName
2
foodCalorie
foodName
3
foodCalorie
foodName

RecyclerView shows the same item many times in my app

I've created a match system in my Android program that also includes a chat section which has 2 fragments. The first fragment shows your chats, the second one shows your matches by using RecyclerView and UsersAdapter. However, in the second (match) fragment, people who you matched with are shown many times. For example, the same person is seen many times as you can see here.
My code is below.
UserFragment:
public class UsersFragment extends Fragment {
private RecyclerView recyclerView;
private UsersAdapter usersAdapter;
private List<User> mUsers;
FirebaseFirestore usersfragmentstore;
FirebaseAuth readauth;
DocumentReference readref;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
usersfragmentstore = FirebaseFirestore.getInstance();
readauth = FirebaseAuth.getInstance();
View view = inflater.inflate(R.layout.fragment_users, container, false);
readref = usersfragmentstore.collection("users").document(readauth.getCurrentUser().getUid());
recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mUsers = new ArrayList<>();
final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("users");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
readref.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
DocumentSnapshot shot = task.getResult();
List<String> matchedid2 = new ArrayList<>();
matchedid2 = (List<String>) shot.get("matchlist");
if (matchedid2.contains(snapshot.getKey())) {
User user = snapshot.getValue(User.class);
mUsers.add(user);
usersAdapter = new UsersAdapter(getContext(), mUsers, false);
recyclerView.setAdapter(usersAdapter);
}
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
return view;
}
}
UserAdapter:
public class UsersAdapter extends RecyclerView.Adapter<UsersAdapter.ViewHolder> {
private Context mContext;
private List<User> mUsers;
private boolean ischat;
String theLastMessage;
public UsersAdapter(Context mContext, List<User> mUsers, boolean ischat) {
this.mUsers = mUsers;
this.mContext = mContext;
this.ischat = ischat;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.user_item_chat, parent, false);
return new UsersAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
User user = mUsers.get(position);
holder.username.setText(user.getName());
if (user.getImageURL().equals("default")) {
holder.profile_image.setImageResource(R.drawable.profilepicture);
} else {
Glide.with(mContext).load(user.getImageURL()).into(holder.profile_image);
}
if (ischat) {
lastMessage(user.getId(), holder.last_msg);
} else {
holder.last_msg.setVisibility(View.GONE);
}
if (ischat) {
if (user.getStatus().equals("online")) {
holder.img_on.setVisibility(View.VISIBLE);
holder.img_off.setVisibility(View.GONE);
} else {
holder.img_on.setVisibility(View.GONE);
holder.img_off.setVisibility(View.VISIBLE);
}
} else {
holder.img_on.setVisibility(View.GONE);
holder.img_off.setVisibility(View.GONE);
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(mContext, MessageActivity.class);
intent.putExtra("userid", user.getId());
mContext.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return mUsers.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView username;
public ImageView profile_image;
private ImageView img_on;
private ImageView img_off;
private TextView last_msg;
public ViewHolder(#NonNull View itemView) {
super(itemView);
username = itemView.findViewById(R.id.chatusername);
profile_image = itemView.findViewById(R.id.profile_image);
img_on = itemView.findViewById(R.id.img_on);
img_off = itemView.findViewById(R.id.img_off);
last_msg = itemView.findViewById(R.id.last_msg);
}
}
private void lastMessage(final String userid, final TextView last_msg) {
theLastMessage = "defalut";
final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Chats");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Chat chat = snapshot.getValue(Chat.class);
if (firebaseUser != null && chat != null) {
if (chat.getReceiver().equals(firebaseUser.getUid()) && chat.getSender().equals(userid) || chat.getReceiver().equals(userid) && chat.getSender().equals(firebaseUser.getUid())) {
theLastMessage = chat.getMessage();
}
}
}
switch (theLastMessage) {
case "default":
last_msg.setText("No message");
break;
default:
last_msg.setText(theLastMessage);
break;
}
theLastMessage = "default";
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
What am I missing?
befor adding new data first clear list by mUsers.clear(); as below
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
readref.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
DocumentSnapshot shot = task.getResult();
List<String> matchedid2 = new ArrayList<>();
matchedid2 = (List<String>) shot.get("matchlist");
if (matchedid2.contains(snapshot.getKey())) {
mUsers.clear();
User user = snapshot.getValue(User.class);
mUsers.add(user);
usersAdapter = new UsersAdapter(getContext(), mUsers, false);
recyclerView.setAdapter(usersAdapter);
}
}
});
}

Categories