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.
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.
Exemples:
ou
https://github.com/greenrobot/EventBus
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
}
}
});
}
}
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();
}
}
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
}
}
}
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();
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.