web-dev-qa-db-fra.com

Comment créer une interface entre Fragment et l'adaptateur?

J'ai fragment avec ListView, disons MyListFragment, et personnalisé CursorAdapter. Je mets onClickListener dans cet adaptateur pour le bouton dans 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 notifier le fragment lorsque le bouton est enfoncé. Comment appeler cette interface?

Aidez-moi, s'il vous plaît.

46
Sabre

Créez 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 créé, la variable d'instance reçoit la référence appropriée à conserver.

Pour appeler le fragment du clic:

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

Lorsque vous créez la Adapter, vous devrez également transmettre votre fragment à l'adaptateur. Par exemple

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

puisque this fera référence à votre fragment, qui est maintenant un AdapterInterface.

Gardez à l'esprit que lors de l'orientation des changements de fragment, il sera probablement recréé. Si votre adaptateur n'est pas recréé, il peut potentiellement conserver une référence à un objet inexistant, provoquant des erreurs.

70
A--C

Utiliser 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

Utilisation d'interfaces:

Je comprends la réponse actuelle, mais il me fallait un exemple plus clair. Voici un exemple de ce que j'ai utilisé avec une Adapter (RecyclerView.Adapter) et une Fragment.

Create Callback Interface:

public interface AdapterCallback {
    void onMethodCallback();
}

Transmettre Callback/Fragment:

Ceci implémentera la interface que nous avons dans notre Adapter. Dans cet exemple, il sera appelé lorsque l'utilisateur cliquera sur un élément de la variable 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
    }
}

Utilisez la Callback dans votre adaptateur:

Dans Fragment, nous avons lancé notre Adapter et l'avons transmis sous forme d'argument au constructeur. Ceci initiera notre interface pour notre méthode de rappel. Vous pouvez constater que nous utilisons notre méthode de rappel pour les clics de l'utilisateur.

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 Utilisez la 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
                }
            }
        });
    }
}
61
Jared Burrows

Suivez les 2 étapes ci-dessous pour recevoir un rappel de Adapter dans Fragment (or Activity)

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èmement: Dans votre Fragment (or Activity), il existe 2 méthodes pour implémenter une méthode de rappel 

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

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

Faire un constructeur comme ça:

  public MyAdapter(Activity activity,AlertMessageBoxOk alertMessageBoxOk) {

  this.mActivity = activity;

  mAlertMessageBoxOk = alertMessageBoxOk;

}

appeler l'interface de l'adaptateur utiliser n'importe quel événement

mAlertMessageBoxOk.onOkClick(5);

après cela, implémentez l'interface AlertMessageBoxOk sur votre fragment comme ceci,

class MyFragment extends Fragment implements AlertMessageBoxOk {

@Override
public void onOkClick(int resultCode) {

  if(resultCode==5){

  enter code here 

      }
    } 
 }
0

une solution pour le NPE est d’abord de fabriquer un correcteur dans votre fragment comme ça

public MyFragment MyFragment(){
        return this;
    }

puis initialisez votre auditeur est un adaptateur comme ça 

Lisener lisener = new MyFragment();
0
mohamed morsi

Ceci est très similaire à la manière dont une activité et un fragment doivent communiquer. Dans le constructeur de votre adaptateur, transmettez une référence à votre fragment, transmettez-la à votre interface et appelez simplement yourReference.buttonPressed () sur votre méthode onClick.

0
Quanturium