15

DialogFragment を作成したアクティビティの DialogFragment から、finish() やその他の非静的メソッドを呼び出すにはどうすればよいですか? DialogFragment の OnClickLisener からメッセージを渡そうとしましたが、役に立ちませんでした。

MainActivity と DialogFragment で構成された、非常に単純なアプリがあります。

    public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle arg0) {
    super.onCreate(arg0);
    setContentView(R.layout.activity);
    showDialog();
}
public void showDialog() {
    DialogFragment newFragment = new ConfirmDialog();
    newFragment.show(getFragmentManager(), "dialog");
}

ダイアログも非常にシンプルです。

public class ConfirmDialog extends DialogFragment {
@Override
public AlertDialog onCreateDialog(Bundle savedInstanceState) {
    // Use the Builder class for convenient dialog construction
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setMessage("Confirm you want to continue?")
           .setPositiveButton("Yes.", new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {
                   //finish() MainActvity
                  }
               })
           .setNegativeButton("No.", new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {
                 //Do nothing in MainActity
               }
           });
    // Create the AlertDialog object and return it
    return builder.create();
}

}

4

3 に答える 3

31

多くのオプションがあります。そのうちの 1 つは、単一のメソッドを内部に持つインターフェイスを定義することです。

  1. ダイアログの呼び出し元にそのインターフェイスを実装してもらいます。
  2. 呼び出し元を指すグローバル変数を保持します。
  3. メソッドに変数を設定しますonAttach(Activity activity)
  4. メソッドでその変数を null にしますonDetach()
  5. で変数 (インターフェイス メンバー) メソッドを呼び出しますonClick

例:

public class MainActivity extends Activity implements MyInterface { 
    // ...

    @Override
    public void onChoose() { finish(); }

}

そして内部ConfirmDialog

public static interface MyInterface {
    public void onChoose();
}

private MyInterface mListener;

@Override
public void onAttach(Activity activity) {
    mListener = (MyInterface) activity;
    super.onAttach(activity);
}

@Override
public void onDetach() {
    mListener = null;
    super.onDetach();
}

そしてmListener.onChoose()、クラス内のどこでも呼び出します。


これが承認済みとしてマークされていることは知っていますが、ディスカッションにさらにフィードバックを提供できると考えました.

インターフェイスを使用するかどうかについての注意。アンディの答えは私のものと同じように機能するため多くのオプションがあります。そのうちの1つは...」と言ったのはそのためです。

ただし、この特定の問題に対して私がインターフェイスを好む理由は、ほとんどの場合、そのような単純な/一般的な確認ダイアログを拡張して再利用するためです。一般的すぎて「無駄」にはなりません (さらに悪いことに、異なるイベント アクションが発生した場合に複製されます)。

それを 1 つの目的 (仕上げ) のために 1 回だけ使用するという確固たる確信がある場合を除き、通常Activity、ダイアログ クラスの の実装の詳細を配線 (および単純化) することは避ける必要があります。柔軟性、抽象化、効率性。維持するコードが少なくなります。

はい、それが必要になる可能性があることを示す証拠publicがあります。特に、自己完結型のクラス ファイルにある場合は、使用しているキーワードであり、再利用が求められます (これも)。Activityそれ以外の場合、実装の詳細はそのクラスにのみ関連するため、main 内にそのクラスを非表示にする必要があります。また、publicキーワードを削除することになります。

はい、複数の に使用できますが、 ingActivityに限定されます。finish()このインターフェイスにより、それぞれの で必要なことを柔軟に行うことができますActivity。つまり、そのイベントに対してそれ自体がどのように動作するかを定義するのは、実装者次第です。実装の詳細は自己完結型です。

補足として、私が行っていることは、アプリケーションに必要なすべてのダイアログを含むパッケージを作成することです。このような確認ダイアログでは、別のメッセージとボタンに再利用します。デフォルトを提供しますが、を使用して変更することもできsetArgumentsます。また、インターフェースを関連させておくので、ダイアログごとに 1 つのインターフェースを作成する必要はありません。実装者は、どのダイアログが「ダイアログ コールバック」をトリガーしたかに応じて応答します。ユーモラスにHydra や Royal Familyと呼ばれるものを避けながら、柔軟性、抽象化、効率性。そう。最後に、私が言ったように、多くのオプションがあります。過度に設計しないでください。ただし、早すぎる時期に単純化しすぎないようにしてください (適切な拡張の余地を残してください)。

これまたは他の答えを選択するよりも、利点と落とし穴を理解することが重要です。

于 2012-11-12T03:51:18.390 に答える
24

finish()インターフェイスを作成するために必要な作業量は少ないですが、インターフェイスを作成したアクティビティから呼び出す必要がある理由がわかりません。finish()DialogFragment自体から呼び出すだけで十分です。何らかの理由で情報を送り返す必要がある場合は、いつでもgetActivity()アクティビティに存在するメソッドを呼び出してチェーンすることができます。最終的には、どこで終了と呼んでも、フラグメントを切り離して破壊します。

フラグメント内のアクティビティからメソッドを呼び出す方法を明確にするためだけに

((YourActivity)getActivity()).someMethod(param);

Javaは、Activityに呼び出したいメソッドがあることを認識していないため、キャストする必要があります。どちらの方法で行くことにしたとしても、頑張ってください:)

乾杯

編集

デビッドの説明に感謝します。一般的にあなたは正しいです。しかし、この場合、正直に言うと、フラグメントの性質とアクティビティとの関係のために、あなたは正しくありません。繰り返しになりますが、基本的には、保持されているActivityクラスとすでに非常に密接な関係にあるフラグメントによって呼び出されるリスナーを作成します。この場合、リスナーを介して何も配線しないことによって提供される利点は失われます。引き続き、すべてのダイアログのカスタムコードを書き直します。私のメソッドでは、Activityクラスにメソッドを書くことができるので、一度だけ書く必要があります。

リスナーを使用する必要があると思う理由は2つだけです。

1.他の人が使用するコードを書いている場合。したがって、特定の構造(AndroidのDatePickerDialogなど)を維持しながら情報を提供する簡単な方法を提供します。

2.接続を維持しようとしている2つの部分の間に接続がない場合(JavaのGUIのように)。

ですから、私はダビデがこれを間違っていると言っているのではありません。人々がいつそれらを使用するかを理解することが重要であるため、彼がそれを提起してくれたことに感謝しています。しかし、繰り返しになりますが、この場合、フラグメントとアクティビティクラスの間の接続のため、彼が言及する利点は存在しません。ここでリスナーが必要ないと私が信じる理由を明らかにしたかっただけです。

于 2012-11-12T04:07:31.807 に答える