RecyclerView blinking on notifyDataSetChanged(); - android

before the moderator take down this question as duplicate please read bellow
Ok I have tried different answers but nothing is working for me for eg I have disabled the animation which doesn't work and I'm trying to use this but I'm not using getItemID so I don't know what to do with it
Here is my Code
Home_Fragment.java // ok I have given only some part of the code that I think is required but if you want to see the entire code please tell me I will update it
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
postRecyclerView.setItemAnimator(null);
getData();
return view;
}
private void getData() {
databaseReference.addValueEventListener(new ValueEventListener() {
#SuppressLint("NotifyDataSetChanged")
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
shimmerFrameLayout.stopShimmer();
shimmerFrameLayout.setVisibility(View.GONE);
postRecyclerView.setVisibility(View.VISIBLE);
mUploads.clear();
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Upload upload = dataSnapshot.getValue(Upload.class);
assert upload != null;
upload.setmKey(dataSnapshot.getKey());
mUploads.add(upload);
}
}
postsAdapter.setUploads(mUploads);
//notify the adapter
postsAdapter.notifyDataSetChanged();
loading = true;
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
loading = true;
}
});
}
PostAdapter_Home.java
public class PostAdapter_Home extends RecyclerView.Adapter<PostAdapter_Home.PostViewHolder> {
public static List<Upload> mUploads;
public Context mcontext;
public PostAdapter_Home(Context context, List<Upload> uploads) {
mUploads = uploads;
mcontext = context;
}
#NonNull
#Override
public PostViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view;
view = LayoutInflater.from(mcontext).inflate(R.layout.ex_home, parent, false);
return new PostViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull PostViewHolder holder, int position) {
Shimmer shimmer = new Shimmer.ColorHighlightBuilder()
.setBaseColor(Color.parseColor("#F3F3F3"))
.setBaseAlpha(1)
.setHighlightColor(Color.parseColor("#E7E7E7"))
.setHighlightAlpha(1)
.setDropoff(50)
.build();
ShimmerDrawable shimmerDrawable = new ShimmerDrawable();
shimmerDrawable.setShimmer(shimmer);
Upload uploadCurrent = mUploads.get(position);
Glide.with(mcontext)
.load(uploadCurrent.getmImageUrl())
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
.placeholder(shimmerDrawable)
.centerCrop()
.fitCenter()
.into(holder.imageView);
// holder.imageView.setOnClickListener(view -> changeScaleType(holder, position));
}
#Override
public int getItemCount() {
return mUploads.size();
}
public void setUploads(List<Upload> uploads){
mUploads=uploads;
}
public static class PostViewHolder extends RecyclerView.ViewHolder {
private final ShapeableImageView imageView;
public PostViewHolder(#NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.imagePostHome);
}
}
}
Upload.java
package com.example.myappnotfinal.AdaptersAndMore;
import com.google.firebase.database.Exclude;
public class Upload {
private String mImageUrl;
private String mKey;
private String mUserName;
private String mComment;
public Upload() {
}
public Upload(String imageUrl) {
mImageUrl = imageUrl;
}
public String getmUserName() {
return mUserName;
}
public void setmUserName(String mUserName) {
this.mUserName = mUserName;
}
public String getmComment() {
return mComment;
}
public void setmComment(String mComment) {
this.mComment = mComment;
}
public String getmImageUrl() {
return mImageUrl;
}
public void setmImageUrl(String mImageUrl) {
this.mImageUrl = mImageUrl;
}
#Exclude
public String getmKey() {
return mKey;
}
#Exclude
public void setmKey(String Key) {
this.mKey = Key;
}
}

Try ListAdapter, it manage these all animations for you. To implement this, we need write some boilerplate classes.
First, let's create the adapter.
public class YourAdapter extends ListAdapter<YourModelClass, YourAdapter.YourViewHolder> {
public YourAdapter(#NonNull DiffUtil.ItemCallback<YourModelClass> diffCallback) {
super(diffCallback);
}
public static class YourViewHolder extends RecyclerView.ViewHolder {
private TextView textViewId;
private TextView textViewName;
private YourViewHolder(View view) {
super(view);
textViewId = view.findViewById(R.id.textViewId);
textViewName = view.findViewById(R.id.textViewName);
}
static YourViewHolder create(ViewGroup parent) {
return new YourViewHolder(
LayoutInflater.from(parent.getContext())
.inflate(
R.layout.your_layout,
parent,
false
)
);
}
void bind(YourModelClass model) {
textViewId.setText(String.valueOf(model.getId()));
textViewName.setText(model.getName());
}
}
#NonNull
#Override
public YourViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return YourViewHolder.create(parent);
}
#Override
public void onBindViewHolder(#NonNull YourViewHolder holder, int position) {
holder.bind(getItem(position));
}
}
now, let's create your class to compare list items with DiffUtill algorithm. In areItemsTheSame you need to use a unique key to compare items. In areContentsTheSame we just compare the both instances.
public class YourItemCallback extends DiffUtil.ItemCallback<YourModelClass> {
#Override
public boolean areItemsTheSame(#NonNull YourModelClass oldItem, #NonNull YourModelClass newItem) {
return oldItem.getId() == newItem.getId();
}
#Override
public boolean areContentsTheSame(#NonNull YourModelClass oldItem, #NonNull YourModelClass newItem) {
return Objects.equals(oldItem, newItem);
}
}
Finally, let's to send data to the adapter. Note that submitList method receive a list of type you specify in adapter
ListAdapter<YourModelClass, YourAdapter.YourViewHolder>
List<YourModelClass> yourList = Arrays.asList(
new YourModelClass(1, "John"),
new YourModelClass(1, "Mac"),
new YourModelClass(1, "Gu"),
new YourModelClass(1, "Gabriel")
);
RecyclerView recyclerView = findViewById(R.id.recyclerView);
YourAdapter yourAdapter = new YourAdapter(new YourItemCallback());
recyclerView.setAdapter(yourAdapter);
yourAdapter.submitList(yourList);

Related

Why the firebase data doesn't appear in the recycler view?

the firebase data doesn't appear in the recycler view
i have some realtimeDb in Google firebase
i try to read it in the recyclerView but nothing appears ,
logcat shows null and here is my code:
1-Here is HomeFragment(Main) Code
public class HomeFragment extends Fragment {
private HomeViewModel homeViewModel;
Unbinder unbinder;
#BindView(R.id.recycler_popular)
RecyclerView recyclerView;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
homeViewModel =
ViewModelProviders.of(this).get(HomeViewModel.class);
View root = inflater.inflate(R.layout.fragment_home, container, false);
unbinder= ButterKnife.bind(this,root);
init();
homeViewModel.getPopularList().observe(this, new Observer<List<PopularCategoryModel>>() {
#Override
public void onChanged(List<PopularCategoryModel> PopularCategoryModel) {
//create adapter
MyPopularCategoriesAdapter adapter = new MyPopularCategoriesAdapter(HomeFragment.this.getContext(), PopularCategoryModel);
recyclerView.setAdapter(adapter);
}
});
return root;
}
private void init() {
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
}
}
2-Here is HomeViewModel Code
public class HomeViewModel extends ViewModel implements IPopularCallbackListener {
private static final String TAG = "HomeViewModel";
private MutableLiveData<List<PopularCategoryModel>> popularList;
private MutableLiveData<String> messageError;
private IPopularCallbackListener popularCallbackListener;
public HomeViewModel() {
}
public MutableLiveData<List<PopularCategoryModel>> getPopularList() {
if (popularList== null){
popularList=new MutableLiveData<>();
messageError=new MutableLiveData<>();
loadPopularList();
}
return popularList;
}
private void loadPopularList() {
final List<PopularCategoryModel> tempList = new ArrayList<>();
DatabaseReference popularRef= FirebaseDatabase.getInstance().getReference(Common.POPULAR_CATEGORY_REF);
popularRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
tempList.clear();
for (DataSnapshot itemSnapShot:dataSnapshot.getChildren()){
PopularCategoryModel model=itemSnapShot.getValue(PopularCategoryModel.class);
tempList.add(model);
Log.d(TAG, "onDataChange:Adel2020"+tempList.size()+popularRef);
}
//popularCallbackListener.onPopularLoadSuccess(tempList);
Log.e(TAG, "Data received:" + tempList.size());
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
popularCallbackListener.onPopularLoadFailed(databaseError.getMessage());
}
});
}
public MutableLiveData<String> getMessageError() {
return messageError;
}
#Override
public void onPopularLoadSuccess(List<PopularCategoryModel> popularCategoryModels) {
popularList.setValue(popularCategoryModels);
}
#Override
public void onPopularLoadFailed(String message) {
messageError.setValue(message);
}
}
3- This is the Adapter
public class MyPopularCategoriesAdapter extends RecyclerView.Adapter<MyPopularCategoriesAdapter.PopViewHolder> {
private List<PopularCategoryModel> listPopularCategoryModel ;
Context context;
public MyPopularCategoriesAdapter( Context context,List<PopularCategoryModel> listPopularCategoryModel) {
this.listPopularCategoryModel = listPopularCategoryModel;
this.context = context;
}
#NonNull
#Override
public PopViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new PopViewHolder(LayoutInflater.from(parent.getContext()).inflate
(R.layout.layout_popular_categories_item, parent, false));
}
#Override
public void onBindViewHolder(#NonNull PopViewHolder holder, int position) {
Glide.with(context).load(listPopularCategoryModel.get(position).getImage()).into(holder.popCategoryImage);
holder.popCategoryName.setText(listPopularCategoryModel.get(position).getName());
}
#Override
public int getItemCount() {
return listPopularCategoryModel.size();
}
public class PopViewHolder extends RecyclerView.ViewHolder {
Unbinder unbinder;
#BindView(R.id.pop_category_name)
TextView popCategoryName;
#BindView(R.id.pop_category_image)
CircleImageView popCategoryImage;
public PopViewHolder(#NonNull View itemView) {
super(itemView);
unbinder= ButterKnife.bind(this,itemView);
}
}
}
4-This is Model
public class PopularCategoryModel {
private String menu_id,food_id,name,image;
public PopularCategoryModel() {
}
public PopularCategoryModel(String menu_id, String food_id, String name, String image) {
this.menu_id = menu_id;
this.food_id = food_id;
this.name = name;
this.image = image;
}
public PopularCategoryModel(String name, String image) {
this.name = name;
this.image = image;
}
+SetterGetter
5-Here is the Data

How to update list in RecyclerView with DiffUtils?

How do you use DiffCallback to load a newList in RecyclerView when DiffUtil ItemCallback is being used.
I would like to give the user the option to return different size lists from the database when the user selects a different size I want the RecyclerView to update.
RecyclerViewAdatper
RecyclerViewAdapter extends ListAdapter<WordEntity, RecyclerViewAdapter.ViewHolder> {
private RecyclerViewAdapter() {
super(DIFF_CALLBACK);
}
private static final DiffUtil.ItemCallback<WordEntity> DIFF_CALLBACK = new DiffUtil.ItemCallback<WordEntiti>() {
#Override
public boolean areItemsTheSame...
#Override
public boolean areContentsTheSame...
};
#Override
public viewHolder onCreateViewHolder...
#Override
public void onVindViewHolder ...
class ViewHolder extends RecyclerView.ViewHolder ...
public void updateWordList(List<WordEntity> words) {
final WordDiffCallBack diffCallBack = new WordDiffCallBack(list???, words);
final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallBack);
this.list???.clear();
this.addAll(words);
diffResult.dispatcheUpdatesTo(this);
}
WordsDiffCallBack
private final List<WordEntity> mOldList;
private final List<WordEntity> mNewList;
public WordsDiffCallBack(List<WordEntity> oldList, List<WordEntity> newList) {
this.mOldList = oldList;
this.mNewList = newList;
}
#Override
public int getOldListSize() {
return mOldList.size();
}
#Override
public int getNewListSize() {
return mNewList.size();
}
#Override
public boolean areItemsTheSame(int OldItemPostion, int newItemPosition) ...
#Override boolean areContentsTheSame(int oldItemPosition, int newItemPosition)...
#Override getChangePayload(int oldItemPosition, int newItemPosition) ...
}
I want the RecycelView to update automatically when the size of the list gets changed by the user. How do I call the old list from the ListAdapter and will that even update the RecyclerView
You can create a template just like shown in this video in youTube:
https://www.youtube.com/watch?v=y31fzLe2Ajw
Here is an example of adapter.
public class CartFragAdapter extends RecyclerView.Adapter<CartFragAdapter.CartFragViewHolder> {
private static final String TAG = "debinf PurchaseAdap";
private static final DiffUtil.ItemCallback<ProductsObject> DIFF_CALLBACK = new DiffUtil.ItemCallback<ProductsObject>() {
#Override
public boolean areItemsTheSame(#NonNull ProductsObject oldProduct, #NonNull ProductsObject newProduct) {
Log.i(TAG, "areItemsTheSame: old is "+oldProduct.getCode()+" ; new is "+newProduct.getCode());
return oldProduct.getCode().equals(newProduct.getCode());
}
#Override
public boolean areContentsTheSame(#NonNull ProductsObject oldProduct, #NonNull ProductsObject newProduct) {
Log.i(TAG, "areContentsTheSame: old is "+oldProduct.getPrice()+" ; new is "+newProduct.getPrice());
return oldProduct.getPrice() == newProduct.getPrice();
}
};
private AsyncListDiffer<ProductsObject> differ = new AsyncListDiffer<ProductsObject>(this, DIFF_CALLBACK);
#NonNull
#Override
public CartFragViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_purchase, parent, false);
return new CartFragViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull CartFragViewHolder holder, int position) {
final ProductsObject purchaseList = differ.getCurrentList().get(position);
holder.mCode.setText(purchaseList.getCode());
holder.mPrice.setText(String.valueOf(purchaseList.getPrice()));
holder.mDescription.setText(purchaseList.getDescription());
}
#Override
public int getItemCount() {
Log.i(TAG, "getItemCount");
return differ.getCurrentList().size();
}
public void submitList(List<ProductsObject> products){
Log.i(TAG, "submitList: products.size is "+products.size());
differ.submitList(products);
}
public class CartFragViewHolder extends RecyclerView.ViewHolder {
public TextView mCode, mPrice, mDescription;
public CartFragViewHolder(#NonNull View itemView) {
super(itemView);
mCode = (TextView) itemView.findViewById(R.id.item_productCode);
mPrice = (TextView) itemView.findViewById(R.id.item_productPrice);
mDescription = (TextView) itemView.findViewById(R.id.item_productDescription);
}
}
}
In MainActivity you call adapter like this:
CartFragAdapter adapter = new CartFragAdapter();
adapter.submitList(inputData);
I hope it helps!
observe this code
here's my diffutil callback
public class MyDiffUtilCallback extends DiffUtil.Callback {
List<String> oldlist;
List<String > newlist;
public MyDiffUtilCallback(List<String> oldlist, List<String> newlist) {
this.oldlist = oldlist;
this.newlist = newlist;
}
#Override
public int getOldListSize() {
return oldlist.size();
}
#Override
public int getNewListSize() {
return newlist.size();
}
#Override
public boolean areItemsTheSame(int olditempostion, int newitemPostion) {
return olditempostion==newitemPostion;
}
#Override
public boolean areContentsTheSame(int olditempostion, int newitemPostion) {
return olditempostion==newitemPostion;
}
#Nullable
#Override
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
return super.getChangePayload(oldItemPosition, newItemPosition);
}
}
here's the recyclerview adpater which uses diffutilcallback
public class recyclerviewAdapter extends RecyclerView.Adapter<recyclerviewAdapter.Viewholder> {
List<String> datasource;
public recyclerviewAdapter(List<String> datasource) {
this.datasource = datasource;
}
#Override
public Viewholder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.demorow,viewGroup,false);
return new Viewholder(itemView);
}
#Override
public void onBindViewHolder(#NonNull Viewholder viewholder, int i) {
viewholder.tv_demo_data_row.setText(datasource.get(i));
}
#Override
public int getItemCount() {
return datasource.size();
}
public static class Viewholder extends RecyclerView.ViewHolder {
TextView tv_demo_data_row;
public Viewholder(#NonNull View itemView) {
super(itemView);
tv_demo_data_row=itemView.findViewById(R.id.tv_demo_data_row);
}
}
//DIFF CALLBACK STATE
public void insertdata(List<String> insertList){
/**
* Insert list insert data to list
*/
MyDiffUtilCallback diffUtilCallback = new MyDiffUtilCallback(datasource,insertList);
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffUtilCallback);
datasource.addAll(insertList);
diffResult.dispatchUpdatesTo(this);
}
public void updateList(List<String> newList){
/**
* update list clear old data and update new data
*/
MyDiffUtilCallback diffUtilCallback = new MyDiffUtilCallback(datasource,newList);
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffUtilCallback);
datasource.clear();
datasource.addAll(newList);
diffResult.dispatchUpdatesTo(this);
}}
and here i can update list in activity on button clickevent
insert_data.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//inserting the data
List<String> insertlist = new ArrayList<>(); //asign old list
for(int i=0;i<2;i++){
insertlist.add(UUID.randomUUID().toString()); // insert new list
adapter.insertdata(insertlist);
faster_recyclerview.smoothScrollToPosition(adapter.getItemCount()-1); //auto scroll to last postion
}
}
});
replace List of string with your modelclass
And in addition to the above (using DiffUtils), if you use Clicks to change RecyclerView's content, make
ViewHolder implements View.OnClickListener
and use this to set OnClickListener in onBindViewHolder
.setOnClickListener(holder);
and get your current position by
this.getAdapterPosition()
private class HistoryRecyclerAdapter extends RecyclerView.Adapter<HistoryRecyclerAdapter.ViewHolder> {
private List<HistoryEntry> entries;
HistoryRecyclerAdapter(List<HistoryEntry> entries) {
this.entries = entries;
}
public void updateContainer(List<HistoryEntry> list){
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffUtil.Callback() {
#Override
public int getOldListSize() { return entries.size(); }
#Override
public int getNewListSize() { return list.size(); }
#Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return entries.get(oldItemPosition).getId()==list.get(newItemPosition).getId();
}
#Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
HistoryEntry old = entries.get(oldItemPosition);
HistoryEntry neww = list.get(newItemPosition);
return old.getExpression().equals(neww.getExpression())
&& old.getResult().equals(neww.getResult());
}
}, false);//detectMoves=true потом позволит вызвать анимацию если строка просто была перемещена
entries = list;
diffResult.dispatchUpdatesTo(this);
}
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
//some Views
final Button delBtn;
ViewHolder(View view){
super(view);
//some Views
delBtn = (Button) view.findViewById(R.id.delete_btn);
}
#Override
public void onClick(View v) {
switch (v.getId()){
//some cases
case R.id.delete_btn:
historyManager.delete(entries.get(this.getAdapterPosition()));
break;
}
}
}
#NonNull
#Override
public HistoryRecyclerAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.history_row, parent, false);
return new HistoryRecyclerAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(HistoryRecyclerAdapter.ViewHolder holder, final int position) {
//some code
holder.delBtn.setOnClickListener(holder);
}
#Override
public int getItemCount() {
return entries.size();
}
}
Early I used final int position in onBindViewHolder and don't understand what's wrong...)))
Here is snapet of my project (How to view list of my providers):
public class ProviderAdapter extends ListAdapter<Provider, RecyclerView.ViewHolder> {
private final GeneralListener<Provider> listener;
public ProviderAdapter(GeneralListener<Provider> listener) {
super(DIFF_CALLBACK);
this.listener = listener;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new ViewHolder(ItemProviderBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
((ViewHolder) holder).bind(getItem(position));
}
class ViewHolder extends RecyclerView.ViewHolder {
ItemProviderBinding binding;
public ViewHolder(ItemProviderBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
void bind(Provider data) {
binding.image.setImageURI(data.img_url);
binding.txtName.setText(data.name);
binding.txtMealTypes.setText(data.meal_types);
binding.txtAddress.setText(data.address);
binding.btnBack.setOnClickListener(view -> {
listener.onClick(Actions.VIEW, data);
});
}
}
private static final DiffUtil.ItemCallback<Provider> DIFF_CALLBACK = new DiffUtil.ItemCallback<Provider>() {
#Override
public boolean areItemsTheSame(#NonNull Provider oldItem, #NonNull Provider newItem) {
return oldItem.id == newItem.id;
}
#Override
public boolean areContentsTheSame(#NonNull Provider oldItem, #NonNull Provider newItem) {
return oldItem.name.equals(newItem.name)
&& oldItem.meal_types.equals(newItem.meal_types)
&& oldItem.address.equals(newItem.address);
}
};
}
To use it:
ProviderAdapter adapter = new ProviderAdapter(new GeneralListener<Provider>() {
#Override
public void onClick(Actions action, Provider provider) {
if (action == Actions.VIEW) {
// TODO: View provider details
}
}
});
recyclerView.setAdapter(adapter);
adapter.submitList(providerList);

How to get onclick item in an android recyclerview and send its attributes to a new activity?

I'm developing an android app for online order. User needs to click on an food item in recyclerView and I'm trying to send the food ID to the AddOrderActivity. How can I get the FId and pass it to the new activity?
CustomerHomeFragment.java
public class CustomerHomeFragment extends Fragment {
private RecyclerView recyclerView;
private FoodsAdapter adapter;
private List<Food> foodList;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_home_customer, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
Call<FoodsResponse> call = RetrofitClient.getInstance().getApi().getFoods();
call.enqueue(new Callback<FoodsResponse>() {
#Override
public void onResponse(Call<FoodsResponse> call, Response<FoodsResponse> response) {
foodList = response.body().getFoods();
adapter = new FoodsAdapter(getActivity(), foodList);
recyclerView.setAdapter(adapter);
}
#Override
public void onFailure(Call<FoodsResponse> call, Throwable t) {
}
});
}
}
public class FoodsAdapter extends RecyclerView.Adapter implements View.OnClickListener{
private Context mCtx;
private List<Food> foodList;
public FoodsAdapter(Context mCtx, List<Food> foodList) {
this.mCtx = mCtx;
this.foodList = foodList;
}
#NonNull
#Override
public FoodsViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mCtx).inflate(R.layout.recyclerview_foods, parent, false);
return new FoodsViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull FoodsViewHolder holder, int position) {
Food food = foodList.get(position);
holder.textViewFName.setText(food.getFName());
holder.textViewUnitPrice.setText(String.format("%d", food.getUnitPrice()));
holder.textViewAvailCount.setText(String.format("%d", food.getAvailCount()));
}
#Override
public int getItemCount() {
return foodList.size();
}
//////////////
#Override
public void onClick(View view) {
Intent intent = new Intent(this.mCtx, AddOrderActivity.class);
this.mCtx.startActivity(intent);
}
/////////////////
class FoodsViewHolder extends RecyclerView.ViewHolder {
TextView textViewFName, textViewUnitPrice, textViewAvailCount;
public FoodsViewHolder(View itemView) {
super(itemView);
textViewFName = itemView.findViewById(R.id.textViewFName);
textViewUnitPrice = itemView.findViewById(R.id.textViewUnitPrice);
textViewAvailCount = itemView.findViewById(R.id.textViewAvailCount);
}
}
}
public class Food {
private int fid, unitprice, availcount;
private String fname;
public Food(int fid, String fname, int unitprice, int availcount) {
this.fid = fid;
this.fname = fname;
this.unitprice = unitprice;
this.availcount = availcount;
}
public int getFId() {
return fid;
}
public String getFName() {
return fname;
}
public int getUnitPrice() {
return unitprice;
}
public int getAvailCount() {
return availcount;
}
}
in the your adapter class inside the onBindViewHolder function add this code
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent=new Intent(context,NoteActivity.class);
intent.putExtra("note_id", currentNote.getNoteId());
intent.putExtra("note_name",currentNote.getNoteName());
intent.putExtra("note_teacher",currentNote.getNoteTeacher());
intent.putExtra("note_university",currentNote.getNoteUniversity());
intent.putExtra("note_image",currentNote.getNoteImage());
intent.putExtra("note_is_downloaded", currentNote.getIsDownloaded());
intent.putExtra("note_storage_path", currentNote.getStoragePath());
intent.putExtra("note_download_link", currentNote.getNoteDownloadLink());
context.startActivity(intent);
}
});

Recyclerview is not showing any data which i have in firebase. Iam able to retrieve the data

HISTOROBJECT.CLASS
public class HistoryObject{
private String mName;
private String mImageUrl;
public HistoryObject(){
}
public HistoryObject(String Name, String Image) {
this.user = Name;
this.msg = Image;
}
private String user, msg;
public String getMsg() {
return msg;
}
public void setMsg(String Name) {
this.msg = Name;
}
public String getUser() {
return user;
}
public void setUser(String Image) {
this.user = Image;
}
}
HISTORYADAPTER.CLASS
public class HistoryAdapter extends RecyclerView.Adapter<HistoryAdapter.ImageViewHolder> {
private Context mContext;
private List<HistoryObject> mUploads;
public HistoryAdapter (Context cx, List<HistoryObject> uploads){
mContext = cx;
mUploads = uploads;
}
#NonNull
#Override
public ImageViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.listofitems, parent, false);
return new ImageViewHolder(v); }
#Override
public void onBindViewHolder(#NonNull ImageViewHolder holder, int position) {
HistoryObject historyObject = mUploads.get(position);
holder.textView.setText(historyObject.getUser());
Picasso.get().load(historyObject.getMsg())
.placeholder(R.mipmap.ic_launcher)
.fit()
.centerCrop()
.into(holder.spapic);
}
#Override
public int getItemCount() {
return mUploads.size() ;
}
public class ImageViewHolder extends RecyclerView.ViewHolder{
public TextView textView;
public ImageView spapic;
public ImageViewHolder(View itemView) {
super(itemView);
textView =(TextView)itemView.findViewById(R.id.nameofspa);
spapic =(ImageView) itemView.findViewById(R.id.spapic);
}
}
}
HOMEPAGE.CLASS
mDatabaseRef = FirebaseDatabase.getInstance().getReference("BeautyCenters");
mDatabaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
// Log.d("SPAA", "VALUE IS " +dataSnapshot) ;
Log.d("SPAA", "postsnap IS " +postSnapshot) ;
HistoryObject upload = postSnapshot.getValue(HistoryObject.class);
mUploads.add(upload);
}
mHistoryAdapter = new HistoryAdapter(HomePage.this, mUploads);
mHistoryRecyclerView.setAdapter(mHistoryAdapter);
mHistoryAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Iam able to retrieve data and can see all list in logcat but it is not displaying in recyclerview. I also want to retrieve the images from the firebase. iam able to show the adapter but the text is not showing in that adapter instead it is blank and also the picture
I have faced this problem before.
Try moving:
mHistoryRecyclerView.setAdapter(mHistoryAdapter);
mHistoryAdapter.notifyDataSetChanged();
out of the listener class to the bottom of onCreate.
If that doesn't work make sure you have this code added:
#Override
public void onStart() {
super.onStart();
if (mAdapter != null) {
mAdapter.startListening();
}
}
If it is still not working then provide a link of your project and I will play around with it.

How to handle RecyclerView positions in a correct way?

I am using a recyclerview and inside its adapter I have another recyclerview.
How to prevent item change and item refresh when an item is updated.
This is creating visual glitches and wrong positioning of the items
I have tried to read directly from a database reference on the current position of the holder.
Result: https://media.giphy.com/media/j6TpXZRE6e44cMZVIP/giphy.gif
public class CommentsAdapter extends RecyclerView.Adapter<CommentsAdapter.ViewHolder>{
private Context mContext;
private List<Comments> mComments;
private List<Replies> allReplies;
public CommentsAdapter(Context mContext, List<Comments> mComments, List<Replies> allReplies )
{
this.mContext = mContext;
this.mComments = mComments;
this.allReplies = allReplies;
}
#NonNull
#Override
public CommentsAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(mContext).inflate(R.layout.all_comments_layout, viewGroup, false);
return new CommentsAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int position)
{
final Comments comments = mComments.get(position);
holder.like.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CommentUps.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
{
if (dataSnapshot.child(PostKey).child(com_uid).hasChild(currentUserID)) {
CommentUps.child(PostKey).child(com_uid).child(currentUserID).removeValue();
CommentsRef.child(PostKey).child(com_uid).child("likes").setValue(comments.getLikes() - 1);
} else {
CommentUps.child(PostKey).child(com_uid).child(currentUserID).setValue(true);
CommentsRef.child(PostKey).child(com_uid).child("likes").setValue(comments.getLikes() + 1);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
});
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Replies");
//reference.orderByChild("pLikes")
reference.orderByChild(com_uid).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
holder.repliesList.clear();
for (DataSnapshot snapshot : dataSnapshot.child(PostKey).child(com_uid).getChildren())
{
Replies replies = snapshot.getValue(Replies.class);
//final String com = comment.toString();
// Log.d(new String("Comments"), com);
//for (String id : followingList)
if (replies.getComment_uid().equals(com_uid))
{
holder.repliesList.add(replies);
}
}
holder.repliesAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public int getItemCount() {
return mComments.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageButton like
List<Replies> repliesList;
RepliesAdapter repliesAdapter;
public ViewHolder(View itemView) {
super(itemView);
like = itemView.findViewById(R.id.comment_like_button);
repliesRecycler = itemView.findViewById(R.id.all_replies_recycler);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mContext);
repliesRecycler.setLayoutManager(linearLayoutManager);
repliesRecycler.setHasFixedSize(true);
repliesList = new ArrayList<>();
repliesAdapter = new RepliesAdapter(mContext, repliesList);
repliesRecycler.setAdapter(repliesAdapter);
repliesAdapter.notifyDataSetChanged();
}
// Second Method - Same Result
private void displayReplies(final String com_uid ,final String PostKey, final boolean locked) {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Replies");
reference.child(PostKey).child(com_uid).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
repliesList.clear();
if (dataSnapshot.exists()) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
final Replies replies = snapshot.getValue(Replies.class);
if (replies.getComment_uid().equals(com_uid)) {
repliesList.add(replies);
repliesAdapter.notifyDataSetChanged();
}
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
My replies adapter:
public class RepliesAdapter extends RecyclerView.Adapter<RepliesAdapter.ViewHolder>
{
public Context mContext;
public List<Replies> mReplies;
public RepliesAdapter(Context mContext, List<Replies> mReplies)
{
this.mContext = mContext;
this.mReplies = mReplies;
}
#NonNull
#Override
public RepliesAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(mContext).inflate(R.layout.all_replies_layout, viewGroup, false);
mAuth = FirebaseAuth.getInstance();
return new RepliesAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int position)
{
final Replies replies = mReplies.get(position);
holder.myUserName.setText(replies.getUsername());
holder.myComment.setText(replies.getReply());
holder.myTime.setText(replies.getTime());
}
#Override
public int getItemCount() {
return mReplies.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView myUserName, myComment,myTime;
public ViewHolder(View itemView) {
super(itemView);
myUserName = itemView.findViewById(R.id.reply_username);
myComment = itemView.findViewById(R.id.reply_text);
myTime = itemView.findViewById(R.id.reply_time);
}
}

Categories

Resources