web-dev-qa-db-ja.com

ダイアログフラグメントからホストフラグメントのボタンクリックを取得する方法

ListItemClickにDialogFragment(Yes/No)を表示したいlistFragmentがあります。 listFragmentでユーザー選択(はい/いいえ)を取り戻したい。リスナーインターフェイスメカニズムについて読みましたが、アクティビティ<->フラグメントで機能します。これを行う1つの方法は次のとおりです。

  1. はい/いいえボタン選択関数を含むダイアログフラグメントでインターフェイスを定義し、アラートダイアログの正/負のボタンクリックでこれらのメソッドを呼び出します。
  2. このインターフェースをメインアクティビティに実装します。
  3. ListFragmentonItemクリックでdialogFragmentを開始します。
  4. ユーザー選択をアクティビティに保存します。
  5. mainアクティビティで実装された別のインターフェイスによってlistFragmentでこの選択を取得します。

しかし、この単純なタスクのための単純なメカニズムはありますか?例やコードはありますか?

22
SohailAziz

DialogFragmentから結果を取得する別の方法があります。

Fragment.setTargetFragment() を使用できます。 DialogFragmentのインスタンスを作成するときは、それにターゲットフラグメントを設定します。次に、DialogFragmentで、このフラグメントを Fragment.getTargetFragment() から取得できます。

たとえば、次のように実行できます。

public interface DialogClickListener {
    public void onYesClick();
    public void onNoClick();
}
public class MyListFragment extends ListFragment implements DialogClickListener {

    ...

    private void showDialog() {
        DialogFragment dialog = new MyDialogFragment();
        dialog.setTargetFragment(this, 0);
        dialog.show(getFragmentManager(), "dialog");
    }

    @Override
    public void onYesClick() {
        // do something
    }

    @Override
    public void onNoClick() {
        // do something
    }
}
public class MyDialogFragment extends DialogFragment {
    private DialogClickListener callback;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        try {
            callback = (DialogClickListener) getTargetFragment();
        } catch (ClassCastException e) {
            throw new ClassCastException("Calling fragment must implement DialogClickListener interface");
        }
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage("message")
                .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        callback.onYesClick();
                    }
                }).setNegativeButton("No", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        callback.onNoClick();
                    }
                });

        return builder.create();
    }
}
75
J-rooft

イベントバスを使用して、コンポーネント間の通信を容易にすることもできます。 Ottoは、ここで利用できる優れたライブラリです-> https://github.com/square/otto 。それはSquareの人たちによって作られているので、あなたはその質の高いオープンソースプロジェクトを知っています。

リポジトリには、使いやすさを示すサンプルがあります。

2
Marco RS