如何在回收器视图适配器中获取上下文

How to get a context in a recycler view adapter

我正在尝试使用 picasso 库将 url 加载到 imageView,但我无法让 context 正确使用 picasso 库。

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();
    }

}

创建 FeedAdapter 的构造函数:

Context context; //global
public FeedAdapter(Context context)
{
   this.context = context;  
}

并在 Activity

FeedAdapter obj = new FeedAdapter(this);

首先全局声明

Context mContext;

通过修改构造函数传递上下文。

public FeedAdapter(List<Post> myDataset, Context context) {
    mDataset = myDataset;
    this.mContext = context;
}

然后在需要的地方使用mContext

这里有几个选项:

  1. Context 作为参数传递给 FeedAdapter 并将其保留为 class 字段
  2. 使用依赖注入在需要时注入Context。我强烈建议阅读它。有一个很棒的工具 -- Dagger by Square
  3. 从任何 View 对象中获取它。在您的情况下,这可能对您有用:

    holder.pub_image.getContext()

    因为 pub_imageImageView.

首先添加一个全局变量

Context mContext;

然后将你的构造函数改成这个

public FeedAdapter(Context context, List<Post> myDataset) {
    mContext = context;
    mDataset = myDataset;
}

创建适配器时传递上下文。

FeedAdapter myAdapter = new FeedAdapter(this,myDataset);

编辑 由于solidak said in ,原来的答案可能会导致内存泄漏问题,使用这种方法是一种不好的做法,所以最好使用另一种方法来访问上下文。

原回答:

您可以添加一个全局变量:

private Context context;

然后从这里分配上下文:

@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;
}

快乐编码:)

您可以使用 pub_image 上下文 (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);


}

你可以这样使用view.getContext()

例子

holder.tv_room_name.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            Toast.makeText(v.getContext(), "", Toast.LENGTH_SHORT).show();


        }
    });

你可以使用这个:

itemView.getContext()

简答:

Context context;

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
    context = recyclerView.getContext();
}

解释为什么其他答案不是很好:

  1. 完全没有必要将 Context 传递给适配器,因为 RecyclerView 您可以从 class
  2. 内部访问它
  3. ViewHolder 级别获得 Context 意味着您每次绑定或创建 ViewHolder 时都会这样做。您重复操作。
  4. 我认为您不必担心任何内存泄漏。如果你的适配器在你的 Activity 生命周期之外徘徊(这很奇怪)那么你已经有泄漏了。

您可以定义:

Context ctx; 

并在 onCreate 上将 ctx 初始化为:

ctx=parent.getContext(); 

注意:Parent 是一个 ViewGroup。

View mView;
mView.getContext();

如果您在布局上使用数据绑定,您可以从 holder 获得 context。下面是一个例子。

@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));
}

解决方案:

使用视图绑定时使用

holder.binding.productImg.context

否则使用

holder.productImg.context

镇痛丸:)