web-dev-qa-db-ja.com

フラグメントとアダプター間のインターフェースを作成する方法は?

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

ボタンが押されたときにフラグメントを通知する必要があります。このインターフェースを呼び出す方法は?

助けてください。

49
Sabre

新しいコンストラクターとインスタンス変数を作成します。

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になっています。

フラグメントの変更の方向については、ほとんどの場合再作成されることに注意してください。アダプタが再作成されない場合、存在しないオブジェクトへの参照が保持される可能性があり、エラーが発生します。

73
A--C

イベントバスの使用:

例:

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で使用したものの例を次に示します。

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
                }
            }
        });
    }
}
63
Jared Burrows

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();     
    }          
}
_
28
Phan Van Linh

そのようなコンストラクタを作成します。

  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();
0
mohamed morsi

これは、アクティビティとフラグメントが通信する方法に非常に似ています。アダプターのコンストラクターで、フラグメントの参照を渡し、それをインターフェイスにキャストして、onClickメソッドでyourReference.buttonPressed()を呼び出すだけです。

0
Quanturium