2015-08-21 20 views
68

Próbuję użyć biblioteki Picasso, aby móc załadować adres URL do obrazuViewView, ale nie jestem w stanie uzyskać poprawnie używać biblioteki Picasso.Jak uzyskać kontekst w adapterze widoku recyklingu

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

} 

Odpowiedz

148

masz kilka opcji tutaj:

  1. przepustkę Context jako argument do FeedAdapter i zachować je jako klasy pola
  2. Wykorzystanie zależności wstrzyknięcie, aby wstrzyknąć Context, gdy jest to potrzebne. Gorąco zachęcam do lektury. Jest na to wspaniałe narzędzie - Dagger przez Square
  3. Pobierz z dowolnego obiektu View. W twoim przypadku to może pracować dla Ciebie:

    holder.pub_image.getContext()

    Jak pub_image jest ImageView.

+17

Preferuję trzecią opcję, pobierając kontekst z widoku. Jest to najprostsze i najprostsze rozwiązanie. – Richard

+0

lub, o wiele lepiej, przekazać w instancji Picasso, zamiast trzymać instancji Picasso w instancji klasy i leniwie ładować ją. –

+2

Każdy obiekt ViewHolder zawiera instancję itemView przekazywaną do konstruktora. Użyj tego w następujący sposób: itemView.getContext() –

2

Tworzenie konstruktora FeedAdapter:

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

i aktywności

FeedAdapter obj = new FeedAdapter(this); 
3

Pierwszy globalnie zadeklarować

Context mContext;

Przeprowadź kontekst z konstruktorem, modyfikując go.

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

następnie użyć mContext gdziekolwiek jest to potrzebne

1

Pierwszy dodać zmienną globalną

Context mContext; 

Następnie zmienić konstruktora do tego

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

The zdać kontekst podczas tworzenia adaptera.

FeedAdapter myAdapter = new FeedAdapter(this,myDataset); 
14

Możesz dodać zmienną globalną:

private Context context; 

następnie przypisać kontekst stąd:

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

Szczęśliwy Codding :)

+0

To działa Dzięki –

+0

Pracował również dla mnie! Dzięki –

+7

Zdecydowanie sugeruję, aby PRZECIWKO mieć globalne odniesienia do kontekstu. Może to prowadzić do strasznych problemów z wyciekiem pamięci !! – Solidak

11

można wykorzystywać kontekst 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); 


} 
3

Możesz używać w ten sposób widoku .getContext()

Przykład

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

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


     } 
    }); 
1

można użyć to:

itemView.getContext() 
+0

Dlaczego zostało to odrzucone? – fobbymaster

1

Krótka odpowiedź:

Context context; 

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

Wyjaśnienie dlaczego inne odpowiedzi nie są wielkie:

  1. Przechodząc Context do zasilacza jest całkowicie zbędne, ponieważ RecyclerView można uzyskać do niego dostęp od wewnątrz klasy
  2. Uzyskanie Context na ViewHolder poziomie oznacza, że ​​robisz to za każdym razem, gdy wiązania lub utworzyć ViewHolder. Duplikujesz operacje.
  3. Nie sądzę, że musisz się martwić o wyciek pamięci. Jeśli Twój adapter pozostanie poza okresem życia Activity (co byłoby dziwne), wówczas masz już wyciek.