How to get a context in a recycler view adapter

JavaAndroidAndroid RecyclerviewPicassoAndroid Context

Java 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:

  1. Pass Context as an argument to FeedAdapter and keep it as class field

  2. 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

  3. Get it from any View object. In your case this might work for you:

    holder.pub_image.getContext()

    As pub_image is a ImageView.

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:

  1. Passing Context to the adapter is completely unnecessary, since RecyclerView you can access it from inside the class
  2. Obtaining Context at ViewHolder level means that you do it every time you bind or create a ViewHolder. You duplicate operations.
  3. 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 :)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionStranger B.View Question on Stackoverflow
Solution 1 - JavapelotasplusView Answer on Stackoverflow
Solution 2 - JavaFarhad NavayazdanView Answer on Stackoverflow
Solution 3 - JavaMaciej BeimcikView Answer on Stackoverflow
Solution 4 - JavaAhmad AghazadehView Answer on Stackoverflow
Solution 5 - Java张家宝View Answer on Stackoverflow
Solution 6 - JavaArpit PatelView Answer on Stackoverflow
Solution 7 - JavaMarcos vitouleyView Answer on Stackoverflow
Solution 8 - JavaKaranView Answer on Stackoverflow
Solution 9 - JavaBlue_AlienView Answer on Stackoverflow
Solution 10 - JavaRohit DaftariView Answer on Stackoverflow
Solution 11 - JavaAKTView Answer on Stackoverflow
Solution 12 - JavaCharles SoaresView Answer on Stackoverflow
Solution 13 - JavaAli AkramView Answer on Stackoverflow