How to get a context in a recycler view adapter
JavaAndroidAndroid RecyclerviewPicassoAndroid ContextJava Problem Overview
I'm trying to use picasso library to be able to load url to imageView, but I'm not able to get the context
to use the picasso library correctly.
public class FeedAdapter extends RecyclerView.Adapter<FeedAdapter.ViewHolder> {
private List<Post> mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView txtHeader;
public ImageView pub_image;
public ViewHolder(View v) {
super(v);
txtHeader = (TextView) v.findViewById(R.id.firstline);
pub_image = (ImageView) v.findViewById(R.id.imageView);
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public FeedAdapter(List<Post> myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
@Override
public FeedAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.feedholder, parent, false);
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder.txtHeader.setText(mDataset.get(position).getPost_text());
Picasso.with(this.context).load("http://i.imgur.com/DvpvklR.png").into(holder.pub_image);
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return mDataset.size();
}
}
Java Solutions
Solution 1 - Java
You have a few options here:
-
Pass
Context
as an argument to FeedAdapter and keep it as class field -
Use dependency injection to inject
Context
when you need it. I strongly suggest reading about it. There is a great tool for that -- Dagger by Square -
Get it from any
View
object. In your case this might work for you:holder.pub_image.getContext()
As
pub_image
is aImageView
.
Solution 2 - Java
Edit As solidak said in the comments section, the original answer could lead to memory leak issues, and it's a bad practice to use this method, so it's better to use another method to access the context.
Original answer:
You can add a global variable:
private Context context;
then assign the context from here:
@Override
public FeedAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {
// create a new view
View v=LayoutInflater.from(parent.getContext()).inflate(R.layout.feedholder, parent, false);
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(v);
// set the Context here
context = parent.getContext();
return vh;
}
Happy Codding :)
Solution 3 - Java
Short answer:
Context context;
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
context = recyclerView.getContext();
}
Explanation why other answers are not great:
- Passing
Context
to the adapter is completely unnecessary, sinceRecyclerView
you can access it from inside the class - Obtaining
Context
atViewHolder
level means that you do it every time you bind or create aViewHolder
. You duplicate operations. - I don't think you need to worry about any memory leak. If your adapter lingers outside your
Activity
lifespan (which would be weird) then you already have a leak.
Solution 4 - Java
You can use pub_image context (holder.pub_image.getContext()
) :
@Override
public void onBindViewHolder(ViewHolder ViewHolder, int position) {
holder.txtHeader.setText(mDataset.get(position).getPost_text());
Picasso.with(holder.pub_image.getContext()).load("http://i.imgur.com/DvpvklR.png").into(holder.pub_image);
}
Solution 5 - Java
you can use this:
itemView.getContext()
Solution 6 - Java
You can use like this view.getContext()
Example
holder.tv_room_name.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "", Toast.LENGTH_SHORT).show();
}
});
Solution 7 - Java
You can define:
Context ctx;
And on onCreate
initialise ctx
to:
ctx=parent.getContext();
Note: Parent is a ViewGroup.
Solution 8 - Java
Create a constructor of FeedAdapter :
Context context; //global
public FeedAdapter(Context context)
{
this.context = context;
}
and in Activity
FeedAdapter obj = new FeedAdapter(this);
Solution 9 - Java
First globally declare
Context mContext;
pass context with the constructor, by modifying it.
public FeedAdapter(List<Post> myDataset, Context context) {
mDataset = myDataset;
this.mContext = context;
}
then use the mContext
whereever you need it
Solution 10 - Java
View mView;
mView.getContext();
Solution 11 - Java
First add a global variable
Context mContext;
Then change your constructor to this
public FeedAdapter(Context context, List<Post> myDataset) {
mContext = context;
mDataset = myDataset;
}
The pass your context when creating the adapter.
FeedAdapter myAdapter = new FeedAdapter(this,myDataset);
Solution 12 - Java
If you are using Databinding on layout you can get the context
from holder
. An exemple below.
@Override
public void onBindViewHolder(@NonNull GenericViewHolder holder, int position) {
View currentView = holder.binding.getRoot().findViewById(R.id.cycle_count_manage_location_line_layout);// id of your root layout
currentView.setBackgroundColor(ContextCompat.getColor(holder.binding.getRoot().getContext(), R.color.light_green));
}
Solution 13 - Java
SOLUTION:
When using viewbinding use
holder.binding.productImg.context
Otherwise use
holder.productImg.context
Chill Pill :)