Как создать интерфейс между фрагментом и адаптером?

У меня есть фрагмент с ListView , скажем MyListFragment и пользовательский CursorAdapter . Я устанавливаю onClickListener в этом адаптере для кнопки в строке списка.

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

Мне нужно уведомить фрагмент, когда кнопка нажата. Как вызвать этот интерфейс?

Помоги пожалуйста.

Solutions Collecting From Web of "Как создать интерфейс между фрагментом и адаптером?"

Создайте новый конструктор и переменную экземпляра:

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

Когда Адаптер выполнен, переменной экземпляра будет присвоена правильная ссылка на удержание.

Чтобы вызвать фрагмент из щелчка:

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

При создании Adapter вам также необходимо передать свой фрагмент в адаптер. Например

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

Так как this будет относиться к вашему фрагменту, который теперь является AdapterInterface .

Имейте в виду, что при ориентации изменений Фрагмента он скорее всего будет воссоздан. Если ваш адаптер не воссоздан, он может потенциально поддерживать ссылку на несуществующий объект, вызывая ошибки.

Использование Eventbus:

Примеры:

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

или

https://github.com/greenrobot/EventBus

Использование интерфейсов:

Я понимаю текущий ответ, но мне нужен более ясный пример. Вот пример того, что я использовал с Adapter (RecyclerView.Adapter) и Fragment .

Создать интерфейс Callback :

 public interface AdapterCallback { void onMethodCallback(); } 

Передача в Callback / Fragment :

Это обеспечит interface который у нас есть в нашем Adapter . В этом примере он будет вызываться, когда пользователь нажимает на элемент в RecyclerView .

В вашем 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 в адаптере:

Во Fragment мы инициировали наш Adapter и передали его как аргумент конструктору. Это запустит наш interface для нашего метода обратного вызова. Вы можете видеть, что мы используем наш метод обратного вызова для пользовательских кликов.

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

Или используйте Fragment в вашем адаптере:

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

Следуйте двум шагам ниже для получения обратного вызова от Adapter во Fragment (or Activity)

Первое: в вашем 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); } }); ... } ... } 

Во-вторых: в вашем Fragment (or Activity) есть два способа реализации метода обратного вызова

Способ 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(); } } 

Это очень похоже на способ взаимодействия и фрагмента. В конструкторе вашего адаптера передайте ссылку на свой фрагмент, добавьте его в свой интерфейс и просто вызовите метод yourReference.buttonPressed () в методе onClick.