Geri dönüşümcü görünüm adaptöründe bağlam nasıl elde edilir


130

Url'yi imageView'a yükleyebilmek için picasso kitaplığını kullanmaya çalışıyorum, ancak contextpicasso kitaplığını doğru şekilde kullanamıyorum.

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

}

Yanıtlar:


291

Burada birkaç seçeneğiniz var:

  1. Geçiş ContextFeedAdapter argüman olarak ve sınıf alanı olarak tutmak
  2. Contextİhtiyaç duyduğunuzda enjekte etmek için bağımlılık enjeksiyonu kullanın . Okumanızı şiddetle tavsiye ederim. Bunun için harika bir araç var - Dagger by Square
  3. Herhangi bir Viewnesneden alın . Sizin durumunuzda bu sizin için işe yarayabilir:

    holder.pub_image.getContext()

    As pub_imagea olduğunu ImageView.


66
Görünümden bağlamı elde etmek için üçüncü seçeneği tercih ederim. En basit ve en basit çözümdür.
Dick Lucas

veya çok daha iyisi, sınıf örneğinde bir Picasso örneğini tutmak ve onu tembel olarak yüklemek yerine Picasso örneğini geçirin.
Eric Cochran

8
Her ViewHolder, yapıcıda ilettiğiniz bir itemView örneği içerir. Şunun gibi kullanın: itemView.getContext ()
Andrei Lupsa

2
# 2 yapamazsın, değil mi? Bunu denedim, ancak bu sizin ApplicationContextolacak ve aktiviteye bağlı olmayacak ve Glide içinden bir çalışma zamanı çökmesine yol açacak.
boltup_im_coding

1
# 2'yi kullanmak istemem durumunda bileşen nesnesini adaptöre nasıl geçirebilirim?
Ezio

32

Global değişken ekleyebilirsiniz:

private Context context;

daha sonra buradan bağlamı atayın:

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

Mutlu Kodlama :)


Benim için de çalıştı! Teşekkürler
Kenny Dabiri

21
İçeriğe KARŞI küresel referanslara sahip olmanızı şiddetle öneririm. Bu, korkunç bellek sızıntısı sorunlarına yol açabilir !!
solidak

1
Viewholder'ı alt sınıflarsanız, özel olabilir.
r3dm4n

Adaptör bir RecyclerView'e bağlıysa, o içeriğe yine de ihtiyaç duyulacağı garanti edilir. Bağdaştırıcıyı çıkarabilirseniz, herhangi bir nedenle bu bağdaştırıcıya ayrıldıktan sonra güçlü bir referansınız olmadıkça hala iyidir, bu durumda önbelleğe alınmış bağlamı temizlemeniz gerekir, benzeri bir yöntem onDetachedFromRecyclerViewveya başka bir şey vardır.
androidguy

19

Kısa cevap:

Context context;

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

Diğer yanıtların neden harika olmadığının açıklaması:

  1. Adaptöre Contextgeçiş RecyclerView, sınıfın içinden erişebileceğiniz için tamamen gereksizdir.
  2. Düzeyde edinme Context, ViewHolderbunu her bağladığınızda veya oluşturduğunuzda yaptığınız anlamına gelir ViewHolder. İşlemleri kopyalıyorsunuz.
  3. Herhangi bir hafıza sızıntısı konusunda endişelenmenize gerek olmadığını düşünüyorum. Adaptörünüz ömrünüzün dışında Activitykalıyorsa (ki bu garip olurdu), o zaman zaten bir sızıntınız var demektir.

Bu durumda, onDetachedFromRecyclerView()içeriği uygulayıp serbest bırakmalı mıyız ?
John Pang

@JohnPang, son derece savunmacı olmak istemediğiniz sürece gerçekten değil. Adaptör referansını Aktivite içinde tutarsanız, güvendesiniz.
Maciej Beimcik

17

Pub_image context ( holder.pub_image.getContext()) kullanabilirsiniz :

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


}

6

Şunları tanımlayabilirsiniz:

Context ctx; 

Ve onCreatebaşlangıçta ctx:

ctx=parent.getContext(); 

Not: Ana, bir Görünüm Grubudur.


5

İlk küresel beyan

Context mContext;

yapıcı ile bağlamı değiştirerek geçirin.

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

o mContextzaman ihtiyacın olan her yerde kullan


5

Bu view.getContext () gibi kullanabilirsiniz

Misal

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

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


        }
    });


4

FeedAdapter yapıcısı oluşturun:

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

ve Faaliyette

FeedAdapter obj = new FeedAdapter(this);

2

Önce global bir değişken ekleyin

Context mContext;

Ardından kurucunuzu buna değiştirin

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

Bağdaştırıcıyı oluştururken bağlamınızı aktarın.

FeedAdapter myAdapter = new FeedAdapter(this,myDataset);

1
View mView;
mView.getContext();

Bu kod soruyu çözebilirken, sorunun nasıl ve neden çözüldüğüne dair bir açıklama da dahil olmak üzere , gönderinizin kalitesini artırmaya gerçekten yardımcı olur ve muhtemelen daha fazla oy almanıza neden olur. Sadece şimdi soran kişi için değil, gelecekte okuyucular için soruyu cevapladığınızı unutmayın. Açıklamalar eklemek ve hangi sınırlamaların ve varsayımların geçerli olduğuna dair bir gösterge vermek için lütfen yanıtınızı düzenleyin . Yorumdan
double-beep
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.