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
}
}
ボタンが押されたときにフラグメントを通知する必要があります。このインターフェースを呼び出す方法は?
助けてください。
新しいコンストラクターとインスタンス変数を作成します。
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
になっています。
フラグメントの変更の方向については、ほとんどの場合再作成されることに注意してください。アダプタが再作成されない場合、存在しないオブジェクトへの参照が保持される可能性があり、エラーが発生します。
例:
または
https://github.com/greenrobot/EventBus
私は現在の答えを理解していますが、より明確な例が必要でした。 Adapter
(RecyclerView.Adapter)とFragment
で使用したものの例を次に示します。
Create Callback
Interface:
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
}
}
});
}
}
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);
}
});
...
}
...
}
_
Second: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();
}
}
_
そのようなコンストラクタを作成します。
public MyAdapter(Activity activity,AlertMessageBoxOk alertMessageBoxOk) {
this.mActivity = activity;
mAlertMessageBoxOk = alertMessageBoxOk;
}
任意のイベントを使用して、アダプターからインターフェースを呼び出します
mAlertMessageBoxOk.onOkClick(5);
その後、このようにフラグメントにAlertMessageBoxOkインターフェースを実装し、
class MyFragment extends Fragment implements AlertMessageBoxOk {
@Override
public void onOkClick(int resultCode) {
if(resultCode==5){
enter code here
}
}
}
nPEの解決策は、最初にそのようなフラグメントにコントラクターを作成することです
public MyFragment MyFragment(){
return this;
}
次に、リスナーを初期化して、そのようなアダプターにします
Lisener lisener = new MyFragment();
これは、アクティビティとフラグメントが通信する方法に非常に似ています。アダプターのコンストラクターで、フラグメントの参照を渡し、それをインターフェイスにキャストして、onClickメソッドでyourReference.buttonPressed()を呼び出すだけです。