この質問は何度か出てきて、すべての回答を読みましたが、これを処理するための本当に堅牢な方法は見たことがありません. 私のソリューションでは、呼び出し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
てリスナーを設定します。
ここに問題があります。ダイアログが開いているときにデバイスを回転させて向きを変えると、Activity
とMyDialogFragment
オブジェクトの両方が再作成されます。入力値が台無しにならないようにするために、初期化された値を として設定していますstatic
。これはハックに感じますが、このようなダイアログは一度に 1 つしか表示されないので、問題ありません。問題が発生するのは、戻り値にあります。元のリスナーが呼び出されます。オブジェクトはまだ存在するので問題ありませんが、(存在する) UI を更新する必要がある場合は、新しいインスタンスが UI を制御しているActivity
ため更新されません。 Activity
私が検討している解決策の 1 つはgetActivity()
、ダイアログ クラスを my にキャストしActivity
、呼び出し側で行うのではなく、ダイアログ自体に強制的にリスナーを追加するActivity
ことです。しかし、これはハッキングの雪だるま式のように感じます。
これを適切に処理するためのベストプラクティスは何ですか?