Ich habe Fragment mit ListView
, sage MyListFragment
und custom CursorAdapter
. Ich setze onClickListener
in diesem Adapter für die Schaltfläche in der Listenzeile.
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
}
}
Ich muss Fragment benachrichtigen, wenn der Knopf gedrückt wird. Wie rufe ich diese Schnittstelle auf?
Hilfe bitte.
Erstellen Sie einen neuen Konstruktor und eine Instanzvariable:
AdapterInterface buttonListener;
public MyListAdapter (Context context, Cursor c, int flags, AdapterInterface buttonListener)
{
super(context,c,flags);
this.buttonListener = buttonListener;
}
Wenn der Adapter erstellt wird, erhält die Instanzvariable die richtige Referenz zum Halten.
So rufen Sie das Fragment vom Klick aus auf:
public void onClick(View v) {
buttonListener.buttonPressed();
}
Bei der Erstellung von Adapter
müssen Sie Ihr Fragment auch an den Adapter übergeben. Zum Beispiel
MyListAdapter adapter = new MyListAdapter (getActivity(), myCursor, myFlags, this);
da this
auf Ihr Fragment verweist, das jetzt ein AdapterInterface
ist.
Denken Sie daran, dass bei einer Änderung des Fragments das Fragment höchstwahrscheinlich neu erstellt wird. Wenn Ihr Adapter nicht erneut erstellt wird, kann er möglicherweise einen Verweis auf ein nicht vorhandenes Objekt beibehalten und Fehler verursachen.
Beispiele:
oder
https://github.com/greenrobot/EventBus
Ich verstehe die aktuelle Antwort, brauchte aber ein klareres Beispiel. Hier ist ein Beispiel dafür, was ich mit einer Adapter
(RecyclerView.Adapter) und einer Fragment
verwendet habe.
Variable Callback
anlegen:
public interface AdapterCallback {
void onMethodCallback();
}
Callback
/Fragment
übergeben:
Dies wird die interface
implementieren, die wir in unserer Adapter
haben. In diesem Beispiel wird es aufgerufen, wenn der Benutzer auf ein Element in der RecyclerView
klickt.
In deiner 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
}
}
Verwenden Sie die Callback
in Ihrem Adapter:
In der Fragment
haben wir unsere Adapter
initiiert und als Argument an den Konstruktor übergeben. Dadurch wird unsere interface
für unsere Callback-Methode initiiert. Sie sehen, dass wir unsere Callback-Methode für Klicks von Benutzern verwenden.
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();
}
});
}
}
oder Verwenden Sie die Fragment
in Ihrem Adapter:
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
}
}
});
}
}
Führen Sie die folgenden 2 Schritte aus, um einen Rückruf von Adapter
in Fragment (or Activity)
zu erhalten.
Zuerst: In deiner 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);
}
});
...
}
...
}
Zweitens: In Ihrer Fragment (or Activity)
gibt es zwei Möglichkeiten, eine Callback-Methode zu implementieren
Weg 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();
}
});
...
}
}
Weg 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();
}
}
Erstellen Sie einen Konstruktor wie diesen:
public MyAdapter(Activity activity,AlertMessageBoxOk alertMessageBoxOk) {
this.mActivity = activity;
mAlertMessageBoxOk = alertMessageBoxOk;
}
aufruf der Schnittstelle von Adapter verwenden Sie ein beliebiges Ereignis
mAlertMessageBoxOk.onOkClick(5);
danach implementieren Sie die AlertMessageBoxOk-Schnittstelle wie folgt in Ihr Fragment.
class MyFragment extends Fragment implements AlertMessageBoxOk {
@Override
public void onOkClick(int resultCode) {
if(resultCode==5){
enter code here
}
}
}
eine Lösung für NPE besteht darin, zunächst einen Konstruktor in Ihrem Fragment zu erstellen
public MyFragment MyFragment(){
return this;
}
dann initialisieren Sie Ihren Listener Adapter so
Lisener lisener = new MyFragment();
Dies ist der Art und Weise, wie eine Aktivität und ein Fragment kommunizieren sollen, sehr ähnlich. Übergeben Sie im Konstruktor Ihres Adapters eine Referenz Ihres Fragments, gießen Sie es in Ihre Schnittstelle und rufen Sie einfach yourReference.buttonPressed () für Ihre onClick-Methode auf.