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

Str*_* B. 116 java android android-context picasso android-recyclerview

我正在尝试使用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();
    }

}
Run Code Online (Sandbox Code Playgroud)

pel*_*lus 239

你有几个选择:

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

    holder.pub_image.getContext()

    就像pub_image一个ImageView.

  • 我更喜欢第三种选择,从视图中获取上下文.这是最简单,最直接的解决方案. (50认同)
  • 每个ViewHolder都包含您在构造函数中传递的itemView实例.使用这样的:itemView.getContext() (7认同)
  • 你不能做#2,是吗?我试过了,但这最终会成为你的“ApplicationContext”,而不是与活动相关联,从而导致 Glide 内部的运行时崩溃。 (2认同)
  • 如果我想使用#2,如何将组件对象传递给适配器? (2认同)

Far*_*cxX 26

您可以添加全局变量:

private Context context;
Run Code Online (Sandbox Code Playgroud)

然后从这里分配上下文:

@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;
}
Run Code Online (Sandbox Code Playgroud)

快乐的Codding :)

  • 我强烈建议AGAINST对Context有全局引用.这可能会导致可怕的内存泄漏问题! (17认同)

Ahm*_*deh 16

您可以使用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);


}
Run Code Online (Sandbox Code Playgroud)


tau*_*las 15

简短回答:

Context context;

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
    context = recyclerView.getContext();
}
Run Code Online (Sandbox Code Playgroud)

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

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


小智 8

你可以使用这个:

itemView.getContext()
Run Code Online (Sandbox Code Playgroud)


小智 6

您可以定义:

Context ctx; 
Run Code Online (Sandbox Code Playgroud)

onCreate初始化ctx为:

ctx=parent.getContext(); 
Run Code Online (Sandbox Code Playgroud)

注意:Parent 是一个 ViewGroup。


blo*_*ala 5

创建 FeedAdapter 的构造函数:

Context context; //global
public FeedAdapter(Context context)
{
   this.context = context;  
}
Run Code Online (Sandbox Code Playgroud)

并在活动中

FeedAdapter obj = new FeedAdapter(this);
Run Code Online (Sandbox Code Playgroud)


Blu*_*ien 5

首先是全球宣布

Context mContext;

通过修改它来传递上下文与构造函数.

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

然后使用mContext你需要的东西


Arp*_*tel 5

您可以像这样使用view.getContext()

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

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


        }
    });
Run Code Online (Sandbox Code Playgroud)