Firestore - RecycleView - Image holder - java

I don't know how to write a holder for an image. I already have 2 texts set, but I don't know what the holder for the image should look like. Can you help me tell what the writeup for the image should look like in order for it to appear correctly?
holder.artistImage.setImageResource(model.getArtistImage());
My code:
public class ArtistsAdapter extends FirestoreRecyclerAdapter<ArtistsModel, ArtistsAdapter.holder> {
/**
* Create a new RecyclerView adapter that listens to a Firestore Query. See {#link
* FirestoreRecyclerOptions} for configuration options.
*
* #param options
*/
public ArtistsAdapter(#NonNull FirestoreRecyclerOptions<ArtistsModel> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull holder holder, int position, #NonNull ArtistsModel model) {
holder.artistName.setText(model.getArtistName());
holder.artistClass.setText(model.getArtistClass());
}
#NonNull
#Override
public holder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.artistrow, parent, false);
return new holder(view);
}
class holder extends RecyclerView.ViewHolder{
TextView artistName, artistClass;
ImageView artistImage;
public holder(#NonNull View itemView) {
super(itemView);
View view = itemView;
artistName = view.findViewById(R.id.tvartist_name);
artistClass = view.findViewById(R.id.tvartist_class);
artistImage = view.findViewById(R.id.ivartist_photo);
}
}

You can use a library like Glide or Picasso to load the image from a given URL. Both libraries have lots of extra options for things like making the image round, adding a placeholder image while it loads, or adding an error image to show if it can't load.
With Glide:
You can pass in a context to the adapter constructor, or get it from the holder root view to use with Glide
#Override
protected void onBindViewHolder(#NonNull holder holder, int position, #NonNull ArtistsModel model) {
holder.artistName.setText(model.getArtistName());
holder.artistClass.setText(model.getArtistClass());
Glide.with(holder.itemView)
.load(model.getArtistImage())
.into(holder.artistImage);
}
With Picasso:
#Override
protected void onBindViewHolder(#NonNull holder holder, int position, #NonNull ArtistsModel model) {
holder.artistName.setText(model.getArtistName());
holder.artistClass.setText(model.getArtistClass());
Picasso.get()
.load(model.getArtistImage())
.into(holder.artistImage);
}

Related

Displaying User Images to CardView from Firebase using Picasso Not Working

I am trying to display images from my Firebase storage and realtime database to a CardView in my Android application. I have saved the images to the Firebase Storage and as a Url node under the specific user (dog). The CardView displays the dogs registered under each owner and each dog has its own profile picture essentially.. which I would like to display on the UI.
I am using Picasso as it was used within the tutorial I found, and seemed to be working, however it is trying to find 'context' within my DogUserAdapter, which is returning null. I wasn't previously using Context context as I am utilising a callback function instead on this particular CardView. What else can I use here to display the image from the database?
DogUserAdapter
public class DogUserAdapter extends FirebaseRecyclerAdapter<Dog, DogUserAdapter.DogViewHolder> {
private DogCallback dogCallback;
private Context context;
public DogUserAdapter(#NonNull FirebaseRecyclerOptions<Dog> options, #NonNull final DogCallback dogCallback) {
super(options);
this.dogCallback = dogCallback;
this.context = context;
}
#Override
protected void onBindViewHolder(#NonNull DogViewHolder holder, int position, #NonNull Dog model) {
holder.dogName.setText(model.getName());
Picasso.with(context)
.load(model.getImageUrl())
.into(holder.dogImage);
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dogCallback.onCardViewClick(model);
}
});
}
#NonNull
#Override
public DogViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.dog, parent, false);
return new DogUserAdapter.DogViewHolder(view);
}
public class DogViewHolder extends RecyclerView.ViewHolder {
TextView dogName;
ImageView dogImage;
CardView cardView;
public DogViewHolder(#NonNull View itemView) {
super(itemView);
dogName = itemView.findViewById(R.id.dogName);
dogImage = itemView.findViewById(R.id.dogImage);
cardView = itemView.findViewById(R.id.card_view_dog);
}
}
public interface DogCallback{
void onCardViewClick(final Dog dog);
}
}
CardView
Firebase Hierarchy
Patrick is right. You do not need context for picasso
Picasso.get().load(url).into(imageView);

How to change an image in RecyclerView locally using drawable

I'm trying to change the image in a RecyclerView with a local drawable image. So in the project the RecyclerView is getting data from a local database, when a boolean column gets true, it should change into a tick. My item view looks like this.
And when the column is true, that clock symbol changes to tick. Here is the code which I tried:
My Adapter code:
public class HawbListAdapter extends RecyclerView.Adapter<HawbListAdapter.MyViewHolder> {
private Context context;
private ArrayList<HawbLists> hawbLists;
private DatabaseHelper mDatabaseHelper;
public HawbListAdapter(Context context, ArrayList<HawbLists> hawbLists) {
this.context = context;
this.hawbLists = hawbLists;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.hawb_list, parent, false);
return new MyViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.Hcode.setText(hawbLists.get(position).getHawbCode());
holder.name.setText(hawbLists.get(position).getName());
if (hawbLists.get(position).isTick()) {
holder.timeImage.setImageResource(R.drawable.ic_right);
}
//Picasso.get().load(hawbLists.get(position).isTick()).into(holder.timeImage);
//holder.timeImage.setImageResource(R.drawable.ic_right);
}
#Override
public int getItemCount() {
return hawbLists.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
private TextView Hcode;
private TextView name;
private ImageView timeImage;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
Hcode = itemView.findViewById(R.id.hawbCode12345);
name = itemView.findViewById(R.id.name_hawb_list);
timeImage = itemView.findViewById(R.id.timeImage);
}
}
}
even when I'm using this
if (hawbLists.get(position).isTick()) {
holder.timeImage.setImageResource(R.drawable.ic_right);
}
and one of the items is true, it is still showing the same clock (wait) symbol, but If I use this:
if (!hawbLists.get(position).isTick()) {
holder.timeImage.setImageResource(R.drawable.ic_right);
}
then all of them regardless of true or false turn into tick mark. Unable to figure out where I'm doing it wrong.
Try this:
if (hawbLists.get(position).isTick()){
holder.timeImage.setImageResource(R.drawable.ic_right);
} else {
holder.timeImage.setImageResource(R.drawable.ic_not_ticked);
}
Do you know about the concept of recycling? Look at your list in the device and see how many rows you have! Now add up one (as swap view) and it's all the views you have. It means no matter how many entries you have (hawbLists.size()), all of them are created/recycled when you scroll. So you have to consider all the possible cases of your item children. Because otherwise a recycled view won't change the view state and likely will show irrelevant behavior.

Wrap content of items individually in a Recycler View?

I'm trying to figure out how to do this in the most simple way possible. Setting the recycler view to wrap the content of course, adjusts the recycler to the biggest item. Setting it to match_parent adjusts all the items to be the maximum at all times.
Setting the maximum width in the Adapter makes all the items be that size no matter what. Dumbfounded at the moment.
My Adapter class
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.MessageViewHolder> {
private ArrayList<Message> messageList;
private Context context;
private MessageSelectListener messageSelectListener;
public MessageAdapter(Context context, ArrayList<Message> messageList){
this.messageList = messageList;
this.context = context;
}
//Create an interface
public interface MessageSelectListener{
void onMessageClick(Message message, int position);
}
public void setMessageClickListener(MessageSelectListener messageSelectListener){
this.messageSelectListener = messageSelectListener;
}
#NonNull
#Override
public MessageViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_list, parent, false);
RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(lp);
//View view = new TextView(context);
//View rootView = LayoutInflater.from(context).inflate(R.layout.order_list, parent, false);
return new MessageViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MessageViewHolder holder, final int position) {
final Message message = messageList.get(position);
holder.text.setText(message.getMessageText());
holder.text.setBackgroundResource(R.drawable.rounded_corner_white_noborder);
// passing Order and Position as parameter to interface method,
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
messageSelectListener.onMessageClick(message, position);
}
});
}
#Override
public int getItemCount() {
return messageList == null ? 0 : messageList.size();
}
public class MessageViewHolder extends RecyclerView.ViewHolder{
public TextView text;
public Message message;
public MessageViewHolder(#NonNull View itemView) {
super(itemView);
text = (TextView) itemView;
}
}
}
The Solution was to change the layout parameters in the onCreateViewHolder() method to WRAP_CONTENT
#NonNull
#Override
public MessageViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_list, parent, false);
RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.**WRAP_CONTENT**, ViewGroup.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(lp);
//View view = new TextView(context);
//View rootView = LayoutInflater.from(context).inflate(R.layout.order_list, parent, false);
return new MessageViewHolder(view);
}

The RecylerView items are not showing

I'm trying to implement RecyclerView in an app. I followed the android hive guide but the items won't show. After a lot of checks I still couldn't find the problem.
Do I need to use implementation RecylerView in my build.app I'm using androidX
I'm using this RecylcerView in a fragment not activity
My adapter class:
public class CouponsAdapter extends RecyclerView.Adapter<CouponsAdapter.ViewHolder> {
private List<CouponsModel> couponsList;
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView productIds,couponUsage,couponLimit,couponAmount,couponCode,couponType,date;
public ViewHolder(#NonNull View itemView) {
super(itemView);
productIds=(TextView)itemView.findViewById(R.id.products_ids);
couponUsage=(TextView)itemView.findViewById(R.id.usage_limit);
couponAmount=(TextView)itemView.findViewById(R.id.coupon_amount);
couponCode=(TextView)itemView.findViewById(R.id.coupon_code);
couponType=(TextView)itemView.findViewById(R.id.coupon_type);
date=(TextView)itemView.findViewById(R.id.date);
}
}
public CouponsAdapter (List<CouponsModel> couponsList){
this.couponsList=couponsList;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.coupons_list,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
CouponsModel couponsModel=couponsList.get(position);
holder.date.setText(couponsModel.getDate());
holder.couponType.setText(couponsModel.getCouponType());
holder.couponCode.setText(couponsModel.getCouponCode());
holder.couponAmount.setText(couponsModel.getCouponAmount());
holder.couponUsage.setText(couponsModel.getCouponUsage());
holder.productIds.setText(couponsModel.getProductIds());
}
#Override
public int getItemCount() {
if(couponsList.size() == 0)
return 1;
return couponsList.size();
}
My fragment :
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.fragment_coupons, container, false);
recyclerView=view.findViewById(R.id.coupons_recyler_view);
couponsAdapter=new CouponsAdapter(couponsModelList);
recyclerView.setAdapter(couponsAdapter);
int x=32;
couponsModelList.add(new CouponsModel(x,x,x,x,"free50","free",x));
couponsAdapter.notifyDataSetChanged();
return view;
}
You should set Layout Manager to your RecyclerView.
If layout manager is not set, you will get the following error: No layout manager attached; Skipping layout
You are missing Layout-manager .Just add this line to your code.
recyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));

Android Studio Firebase Get Data [duplicate]

This question already has an answer here:
I cant see any FirebaseRecyclerAdapter items on my layout
(1 answer)
Closed 3 years ago.
I am trying to use android studio to get firebase data and display it on the screen. I am trying to display anything that is in the database related to it to a RecyclerView. But the data does not return and nothing displays (no error statement). Any ideas why?
private void firebaseLotSearch() {
Toast.makeText(BuyingParking.this,"Started Search",Toast.LENGTH_LONG).show();
Query query = mUserDatabase.startAt(searchText).endAt(searchText+"\uf8ff");
FirebaseRecyclerOptions<Lot_Location> options =
new FirebaseRecyclerOptions.Builder<Lot_Location>()
.setQuery(query, Lot_Location.class)
.build();
// Lot_Location.class,R.layout.list_layout,LotViewHolder.class,mUserDatabase
FirebaseRecyclerAdapter<Lot_Location,LotViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Lot_Location, LotViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull LotViewHolder holder, int position, #NonNull Lot_Location model) {
holder.setDetails(model.getLocation(),model.getAdmin(),model.getPrice());
}
#NonNull
#Override
public LotViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
return null;
}
};
searchParking.setAdapter(firebaseRecyclerAdapter);
}
public class LotViewHolder extends RecyclerView.ViewHolder{
public LotViewHolder(#NonNull View itemView) {
super(itemView);
mView = itemView;
}
public void setDetails(String location,String admin,String price)
{
TextView m_location = (TextView)mView.findViewById(R.id.Lot);
TextView m_admin = (TextView)mView.findViewById(R.id.Admin);
TextView m_price = (TextView)mView.findViewById(R.id.price);
m_location.setText(location);
m_admin.setText(admin);
m_price.setText(price);
}
}
onCreateViewHolder is returning null. You need to return an object of LotViewHolder class.
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View rootView = mInflater.inflate(R.layout.your_item_view, parent, false);
ViewHolder holder = new ViewHolder(rootView);
return holder;
}

Categories