2015-06-16 13 views
19

Sto convertendo ListView della mia app in RecyclerView. Su ListView, è stato molto facile implementare OnClickListener, ma in RecyclerView, dobbiamo farlo in adattatore. Voglio aprire un nuovo frammento quando l'utente fa clic su un elemento. Per fare questo devo chiamare FragmentManager in un adattatore che non sono in grado di fare. Questo è il mio codice di RecyclerAdapter:Come chiamare getFragmentManager su Recycler.Adapter?

public ListItemViewHolder(View itemView) { 
      super(itemView); 
      title = (TextView) itemView.findViewById(R.id.title); 
      description = (TextView) itemView.findViewById(R.id.description); 
      itemView.setOnClickListener(this); 
     } 

     @Override 
     public void onClick(View v) { 
      //Call FragmentManager and add Fragment to it. 
      } 
     } 

Così, come chiamare FragmentManager e aggiungere frammenti in esso. C'è un modo migliore di questo come inviare Broadcast o qualsiasi altro metodo.

+0

evento bolla fino a Recycler.Adapter (come ora si è nel supporto) e impostare qualche ascoltatore per esso (ad esempio, il frammento che crea l'addapter) - come fare questo? è stato descritto qui su SO molte volte – Selvin

+0

@Selvin so come chiamare FragmentManager in attività o frammento ma mi sta dando errore nell'adattatore – MSati

risposta

40

Hai solo bisogno di un contesto di un'attività passata nel costruttore. Assicurati di chiamare new Adapter(this,...) dalle attività e new Adapter(getActivity(),...) dai frammenti.

private Context context; 

@Override 
public void onClick(View v) { 
    FragmentManager manager = ((Activity) context).getFragmentManager(); 
} 
-1

Si potrebbe passare riferimento FragmentManager durante la creazione viewholder così la vostra classe per Viewholder potrebbe essere la seguente

class ListItemViewHolder { 
FragmentManager manager; 
public ListItemViewHolder(View itemView,FragmentManager manager) { 
     super(itemView); 
     title = (TextView) itemView.findViewById(R.id.title); 
     description = (TextView) itemView.findViewById(R.id.description); 
     itemView.setOnClickListener(this); 
     this.manager = manager; 
    } 

    @Override 
    public void onClick(View v) { 
     //Call FragmentManager and add Fragment to it. 
     manager.beginTransaction... 
     } 
    } 
4

L'opzione migliore sarebbe probabilmente di avere il frammento che crea un'istanza della RecyclerAdapter per implementare e l'interfaccia come questa:

public class MyRecyclerAdapter extends Adapter<RecyclerAdapter.ViewHolder> { 

    private ItemType[] mItems; 
    private MRAItemClickedListener mListener; 

    public MyRecyclerAdapter(Context ctx, MRAItemClickedListener listener){ 

     mListener = listener; 
     ... 
    } 

    @Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
     holder.itemView.setOnClickListener(new OnClickListener(){ 
      @Override 
      public void onClick(View v) { 
        mListener.onItemClicked(mItems[position]); 
      } 
     }); 
    } 

    interface MRAItemClickedListener { 
     void onItemClicked(ItemType item); 
    } 

} 

public class MyFragment ... implements MRAItemClickedListener { 

    public void onItemClicked(ItemType item){ 
      // do stuff with item 
    } 

} 
1

So che questo è troppo tardi per voi, ma per chiunque altro possa vedere questo .

Quindi, invece di eseguire m vai, è possibile passare il contesto del frammento al momento della prima inizializzazione dell'adattatore.

Così nel costruttore per l'adattatore è possibile aggiungere un argomento come questo

// variable to hold fragment 
private Fragment fragment; 

public MyCustomAdapter(Fragment fragment) 
{ 
    this.fragment = fragment; 
} 

e nel vostro frammento si può semplicemente inizializzare se come questo

MyCustomAdapter myAdapter = new MyCustomAdapter(this); 

finalmente è possibile chiamare

Fragment fragment = new myNewFragment(); 
FragmentManager fragmentManager = context.getFragmentManager(); 
fragmentManager.beginTransaction().replace(R.id.fragment_container, fragment) 
.commit(); 

in modo da poter iniziare un nuovo frammento

30

Per aggiungere alla risposta approvata: se si ottiene ancora un errore potrebbe essere necessario sostituire questa linea;

FragmentManager manager = ((Activity)context).getFragmentManager(); 

Con questo

FragmentManager manager = ((AppCompatActivity)context).getSupportFragmentManager(); 

Per me questo era perché stavo usando il support.v4.app.FragmentManager al posto del normale fragmentmanager

+1

Ho avuto lo stesso problema.Grazie :) – h8pathak

+1

@ h8pathak felice mi ha aiutato –

+1

Grazie! Questo mi aiuta. – Polar

0

Hai solo bisogno di un contesto di un'attività passata nel costruttore. Assicurati di chiamare il nuovo Adapter(this,...) dalle attività e new Adapter(getActivity(),...) dai frammenti.

private Context context; @Override public void onClick(View v) { FragmentManager manager = ((Activity) context).getFragmentManager();}

Problemi correlati