8

この質問は何度か出てきて、すべての回答を読みましたが、これを処理するための本当に堅牢な方法は見たことがありません. 私のソリューションでは、呼び出しActivityからリスナーを使用してAlertDialogいます。

public class MyDialogFragment extends DialogFragment {

    public interface MyDialogFragmentListener {
        public void onReturnValue(String foo);
    }

    public void init(boolean someValue)
    {
        sSomeValue = someValue;
        listeners = new ArrayList<MyDialogFragmentListener>();
    }
    static boolean sSomeValue;
    private static ArrayList<MyDialogFragmentListener> listeners;

    public void addMyDialogFragmentListener(MyDialogFragmentListener l)
    {
        listeners.add(l);
    }

    public void removeMyDialogFragmentListener(MyDialogFragmentListener l)
    {
        listeners.remove(l);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle(R.string.title)
           .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int id) {
                   for (MyDialogFragmentListener listener : listeners) {
                       listener.onReturnValue("some value");
                   }
               }
           })
           .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {
                   // User cancelled the dialog
                   // Nothing to do but exit
               }
           });
        if (sSomeValue) {
            builder.setMessage(R.string.some_value_message);
        } else {
            builder.setMessage(R.string.not_some_value_message);
        }
        // Create the AlertDialog object and return it
        return builder.create();
    }
}

次に、呼び出しActivityでオブジェクトを通常どおりインスタンス化し、引数を渡しinitてリスナーを設定します。

ここに問題があります。ダイアログが開いているときにデバイスを回転させて向きを変えると、ActivityMyDialogFragmentオブジェクトの両方が再作成されます。入力値が台無しにならないようにするために、初期化された値を として設定していますstatic。これはハックに感じますが、このようなダイアログは一度に 1 つしか表示されないので、問題ありません。問題が発生するのは、戻り値にあります。元のリスナーが呼び出されます。オブジェクトはまだ存在するので問題ありませんが、(存在する) UI を更新する必要がある場合は、新しいインスタンスが UI を制御しているActivityため更新されません。 Activity

私が検討している解決策の 1 つはgetActivity()、ダイアログ クラスを my にキャストしActivity、呼び出し側で行うのではなく、ダイアログ自体に強制的にリスナーを追加するActivityことです。しかし、これはハッキングの雪だるま式のように感じます。

これを適切に処理するためのベストプラクティスは何ですか?

4

3 に答える 3

24

あなたは正しい道を進んでいます。私はAndroid Developers - Using DialogFragments article で推奨されている方法に従います。

上記で行ったように、DialogFragment を作成し、Activity が実装するインターフェイスを定義します。

public interface MyDialogFragmentListener {
    public void onReturnValue(String foo);
}

次に、DialogFragment で結果を Activity に返したい場合は、Activity をインターフェイスにキャストします。

@Override
public void onClick(DialogInterface dialog, int id) {
    MyDialogFragmentListener activity = (MyDialogFragmentListener) getActivity();
    activity.onReturnValue("some value");
}

次に、Activityそのインターフェイスを実装して値を取得します。

public class MyActivity implements MyDialogFragmentListener {
    ...
    @Override
    public void onReturnValue(String foo) {
        Log.i("onReturnValue", "Got value " + foo + " back from Dialog!");
    }
}
于 2012-11-17T22:00:49.853 に答える
2

アクティビティがリッスンするダイアログの onClickListner からインテントを起動できます。

ブロードキャスティングとインテントの受信に関するこのチュートリアルをご覧ください

于 2012-11-17T22:00:06.933 に答える
0

かなり古い投稿ですが...

ダイアログクラスに適切な変数がありました:

int selectedFooStatus = 0; 

ダイアログが操作されたときにそれらを操作しました:

.setSingleChoiceItems(FOO_CHOICES, -1, new DialogInterface.OnClickListener() {
                   @Override
                   public void onClick(DialogInterface dialog, int which) {

                       selectedFooStatus = which; 

                   }})

onclick コールバック メソッドでは、返されたフラグメントを適切にキャストし、getter を使用して値を返しました。

    public void onDialogPositiveClick(DialogFragment dialog) {

                ChangeFooStatusDialog returnedDialog = (ChangeFooStatusDialog) dialog;

                this.fooStatus = returnedDialog.getSelectedFooStatus();

}
于 2014-06-24T19:45:33.580 に答える