Comment créer une interface entre Fragment et adaptateur?

j'ai fragment ListView, dire MyListFragment et personnalisé CursorAdapter. Je suis paramètre onClickListener dans cet adaptateur pour le bouton de la ligne de liste.

public class MyListAdapter extends CursorAdapter {

    public interface AdapterInterface {
        public void buttonPressed();
    }

    ...

    @Override
    public void bindView(final View view, final Context context, final Cursor cursor) {
        ViewHolder holder = (ViewHolder) view.getTag();

        ...

        holder.button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // some action
                // need to notify MyListFragment
            }
        });
    }
}

public MyListFragment extends Fragment implements AdapterInterface {

    @Override
    public void buttonPressed() {
        // some action
    }
}

je dois prévenir fragment quand le bouton est pressé. Comment invoquer cette interface?

de l'Aide, s'il vous plaît.

44
demandé sur Sabre 2013-03-16 04:59:14

6 réponses

Faire un nouveau constructeur et une variable d'instance:

AdapterInterface buttonListener;

public MyListAdapter (Context context, Cursor c, int flags, AdapterInterface buttonListener)
{
  super(context,c,flags);
  this.buttonListener = buttonListener;
}

Lorsque l'Adaptateur est fait, la variable d'instance sera donné la référence appropriée à tenir.

Pour appeler le Fragment de la cliquez sur:

public void onClick(View v) {
   buttonListener.buttonPressed();
}

en faisant le Adapter, vous devrez également passer votre Fragment à L'Adaptateur. Par exemple,

MyListAdapter adapter = new MyListAdapter (getActivity(), myCursor, myFlags, this);

depuis this fera référence à votre Fragment, qui est maintenant un AdapterInterface.

Gardez à l'esprit que sur l'orientation du Fragment change, il sera très probablement recréé. Si votre adaptateur n'est pas recréé, il peut potentiellement conserver une référence à un objet inexistant, provoquant des erreurs.

68
répondu A--C 2013-03-16 01:10:20

À L'Aide De Eventbus:

Exemples:

https://github.com/kaushikgopal/RxJava-Android-Samples/tree/master/app/src/main/java/com/morihacky/android/rxjava/rxbus

ou

https://github.com/greenrobot/EventBus

L'Utilisation D'Interfaces:

je comprends la réponse actuelle mais j'avais besoin d'un exemple plus clair. Voici un exemple de ce que j'ai utilisé avec un Adapter(RecyclerView.Adaptateur) et un Fragment.

Créer Callback Interface:

public interface AdapterCallback {
    void onMethodCallback();
}

Passage Callback/Fragment:

ceci implémentera le interface que nous avons dans notre Adapter. Dans cet exemple, il sera appelé lorsque l'utilisateur clique sur un élément dans le RecyclerView.

Dans votre Fragment:

public class MyFragment extends Fragment implements AdapterCallback {

    private MyAdapter mMyAdapter;

    @Override
    public void onMethodCallback() {
       // do something
    }

    @Override
    public void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        this.mMyAdapter = new MyAdapter(this); // this class implements callback
    }
}

Callback dans votre Adaptateur:

Dans le Fragment, nous avons lancé notre Adapter et passé ceci comme argument au constructeur. Cela lancera notre interface pour notre méthode de rappel. Vous pouvez voir que nous utilisons notre méthode de rappel pour les clics.

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private AdapterCallback mAdapterCallback;

    public MyAdapter(AdapterCallback callback) {
        this.mAdapterCallback = callback;
    }

    @Override
    public void onBindViewHolder(final MyAdapter.ViewHolder viewHolder, final int i) {
        // simple example, call interface here
        // not complete
        viewHolder.itemView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mAdapterCallback.onMethodCallback();
            }
        });
    }
}

ou Fragment dans votre adaptateur:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private AdapterCallback mAdapterCallback;

    public MyAdapter(Fragment fragment) {
        try {
            this.mAdapterCallback = ((AdapterCallback) fragment);
        } catch (ClassCastException e) {
            throw new ClassCastException("Fragment must implement AdapterCallback.");
        }
    }

    @Override
    public void onBindViewHolder(final MyAdapter.ViewHolder viewHolder, final int i) {
        // simple example, call interface here
        // not complete
        viewHolder.itemView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    mAdapterCallback.onMethodCallback();
                } catch (ClassCastException exception) {
                   // do something
                }
            }
        });
    }
}
58
répondu Jared Burrows 2016-12-30 21:03:59

suivez les 2 étapes ci-dessous pour recevoir un appel de AdapterFragment (or Activity)

le Premier: Dans votre Adapter

public class ListAdapter extends RecyclerView.Adapter < RecyclerListAdapter.ItemViewHolder > {
    ...
    private ListAdapterListener mListener;

    public interface ListAdapterListener { // create an interface
        void onClickAtOKButton(int position); // create callback function
    }

    public RecyclerListAdapter(Context mContext, ArrayList < Items > listItems, ListAdapterListener mListener) { // add the interface to your adapter constructor
        ...
        this.mListener = mListener; // receive mListener from Fragment (or Activity)
    }
    ...
    public void onBindViewHolder(final ItemViewHolder holder, final int position) {

        holder.btnOK.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // use callback function in the place you want
                mListener.onClickAtOKButton(position);
            }
        });
        ...
    }
    ...
}

Deuxième: Dans votre Fragment (or Activity), il existe 2 moyens pour mettre en œuvre la méthode callback

1

 public MyListFragment extends Fragment {
     ...
     public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
         ...
         ListAdapter adapter = new ListAdapter(getActivity(), listItems, new ListAdapter.ListAdapterListener() {
             @Override
             public void onClickAtOKButton(int position) {
                 Toast.makeText(getActivity(), "click ok button at" + position, Toast.LENGTH_SHORT).show();
             }
         });
         ...
     }
 }

2

public MyListFragment extends Fragment implements ListAdapter.ListAdapterListener {
     ...
     public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        ListAdapter  adapter = new ListAdapter (getActivity(), listItems, this);
        ...   
    }

    @Override
    public void onClickAtOKButton(int position) {  
        Toast.makeText(getActivity(), "click ok button at" + position, Toast.LENGTH_SHORT).show();     
    }          
}
24
répondu Phan Van Linh 2016-05-31 00:30:17

C'est très similaire à la manière d'une activité et un fragment doit communiquer. Dans le constructeur de votre adaptateur, passez une référence de votre fragment, jetez-le à votre interface et appelez simplement votreréférence.buttonPressed () sur votre méthode onClick.

0
répondu Quanturium 2013-03-16 01:05:00

une solution pour NPE est d'abord de faire conctracteur dans votre Fragment comme cela

public MyFragment MyFragment(){
        return this;
    }

alors initialisez votre écouteur est adaptateur comme cela

Lisener lisener = new MyFragment();
0
répondu mohamed morsi 2018-03-30 04:58:12

Faire un constructeur comme ça:

  public MyAdapter(Activity activity,AlertMessageBoxOk alertMessageBoxOk) {

  this.mActivity = activity;

  mAlertMessageBoxOk = alertMessageBoxOk;

}

appeler l'interface à partir de l'adaptateur utiliser tout événement

mAlertMessageBoxOk.onOkClick(5);

après que l'implémentation AlertMessageBoxOk interface à votre fragment comme ceci,

class MyFragment extends Fragment implements AlertMessageBoxOk {

@Override
public void onOkClick(int resultCode) {

  if(resultCode==5){

  enter code here 

      }
    } 
 }
0
répondu Saurabh Gaddelpalliwar 2018-07-31 10:53:06