リサイクラービューアダプターでコンテキストを取得する方法


129

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

}

回答:


290

ここにはいくつかのオプションがあります。

  1. 渡しContextFeedAdapterの引数として、クラスフィールドとしてそれを維持
  2. 依存性注入を使用Contextして、必要なときに注入します。それについて読むことを強く勧めます。そのための素晴らしいツールがあります-Dagger by Square
  3. 任意のViewオブジェクトから取得します。あなたの場合、これはあなたのために働くかもしれません:

    holder.pub_image.getContext()

    そのままpub_imageですImageView


64
私はビューからコンテキストを取得する3番目のオプションを好みます。これは最も単純で最も簡単なソリューションです。
ディックルーカス

または、クラスインスタンスでPicassoインスタンスを保持して遅延読み込みするのではなく、Picassoインスタンスを渡す方がはるかに優れています。
Eric Cochran

8
各ViewHolderには、コンストラクターで渡すitemViewのインスタンスが含まれています。これを次のように使用します。itemView.getContext()
Andrei Lupsa '20

1
#2できないよね?私はそれを試しましたが、これはあなたのものでApplicationContextあり、アクティビティに関連付けられていないことになり、Glide内からのランタイムクラッシュにつながります。
Boltup_im_coding 2018年

#2を使用する場合にコンポーネントオブジェクトをアダプターに渡す方法
エツィオ

32

グローバル変数を追加できます:

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

Happy Codding :)


私も働いた!ありがとう
ケニーダビリ

21
コンテキストへのグローバル参照があることを強くお勧めします。これは恐ろしいメモリリークの問題につながる可能性があります!!
solidak 2017

1
ビューホルダーをサブクラス化する場合、プライベートにすることができます。
r3dm4n 2017年

アダプターがRecyclerViewに接続されている場合、そのコンテキストはとにかく必要であることが保証されます。アダプターを接続解除する場合でも、何らかの理由で、アダプターが切り離された後にこのアダプターへの強い参照を保持しない限り問題はありません。その場合、キャッシュされたコンテキストをクリアする必要がありonDetachedFromRecyclerViewます。などのメソッドがあります。
androidguy 2017

19

短い答え:

Context context;

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

他の回答が良くない理由:

  1. クラス内ContextからアダプターにRecyclerViewアクセスできるため、アダプターへの受け渡しは完全に不要です。
  2. 取得Context時にViewHolder、あなたはそれをあなたがバインドするたびに行うか、作成することをレベル手段ViewHolder。操作を複製します。
  3. メモリリークについて心配する必要はないと思います。アダプターがActivity寿命の外に残っている場合(これは奇妙です)、すでにリークがあります。

この場合、onDetachedFromRecyclerView()コンテキストを実装して解放しますか?
John Pang

@JohnPangは、あなたが非常に守りたいと思わない限り、実際にはありません。アダプタ参照をアクティビティ内に保持する場合は、安全です。
Maciej Beimcik 2018

17

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


}


5

最初にグローバルに宣言する

Context mContext;

変更することにより、コンストラクターでコンテキストを渡します。

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

次に、mContext必要な場所で使用します


5

次のように使用できます。getContext()

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

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


        }
    });

5

あなたはこれを使うことができます:

itemView.getContext()

4

FeedAdapterのコンストラクタを作成します。

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

と活動中

FeedAdapter obj = new FeedAdapter(this);

2

最初にグローバル変数を追加します

Context mContext;

次に、コンストラクタをこれに変更します

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

アダプターの作成時にコンテキストを渡します。

FeedAdapter myAdapter = new FeedAdapter(this,myDataset);

1
View mView;
mView.getContext();

このコードは問題を解決する可能性がありますが、これが問題を解決する方法と理由の説明含めると、投稿の品質が向上し、おそらく投票数が増えることになります。あなたが今尋ねている人だけでなく、あなたが将来の読者のための質問に答えていることを忘れないでください。回答を編集して説明を追加し、適用される制限と前提を示してください。口コミから
回のビープ音
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.