2013-03-16 42 views
33

我有片段ListView,說MyListFragment,和定製CursorAdapter。 我在此適配器中爲列表行中的按鈕設置了onClickListener如何在Fragment和適配器之間創建接口?

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

我需要在按下按鈕時通知片段。如何調用這個接口?

請幫忙。

回答

58

創建一個新的構造函數和一個實例變量:

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

請記住,在片段變化的方向上,它很可能會被重新創建。如果您的適配器未重新創建,它可能會保留對不存在的對象的引用,從而導致錯誤。

+0

我在哪裏放第一部分代碼? AdapterInterface buttonListener; 我試圖將它粘在我的適配器上,但是拋出了一個錯誤。 謝謝 – 2016-06-17 11:29:15

+0

非常感謝你的詳細回答!!!!!!! – Arjun 2017-05-08 07:53:08

0

這與活動和片段應該交流的方式非常相似。在適配器的構造函數中,傳遞片段的引用,將其轉換爲接口,然後在onClick方法上調用yourReference.buttonPressed()。

52

使用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傳球:

這將實現我們在我們的Adapterinterface。在這個例子中,當用戶點擊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 
       } 
      } 
     }); 
    } 
} 
+0

我嘗試了以下FragementActivity ..但我得到NPE:http://pastebin.com/wc2ByiFz - 如果我不使用回調,只是記錄值事情都很好。 – TheDevMan 2015-03-17 11:35:38

+0

@TheDevMan NPE在哪裏?我在我的應用程序的應用程序中使用這種接口方法。 – 2015-03-17 11:39:10

+0

嗯。每當我使用回調,我得到NPE,但是當我不打電話,只是有它的日誌工作。我有詳細的問題在http://stackoverflow.com/questions/29092877/click-event-from-adapter-to -activity-or-fragment-in-android - 你能幫助解決這個問題嗎?我一直在努力解決這個問題。 – TheDevMan 2015-03-17 11:42:17

23

按照以下爲Fragment (or Activity)

首先從Adapter收到回調2個步驟:在你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),有2種方式爲實現回調方法

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

這工作對我來說.. – 2016-11-10 07:46:46

+2

真棒,感謝這個明確的例子 – Juanca 2017-02-03 05:37:59

+1

很酷,這就是我要找的。 – 2017-06-21 10:27:19

相關問題