次のすべての要件 を処理できるダイアログを作成できた人はいますか。
- ローテーションの変更中も保持されます(android:configChanges属性は使用されません)
- スクリーンセーバーをアクティブにして(またはホームに移動して)アクティビティに戻るときに保持されます
- 片方のダイアログをもう一方のダイアログの直後に表示することはできません。
- 一方のダイアログをもう一方のダイアログの直後に表示することは、両方のダイアログに回転を追加することで閉じられます。
2つの連続するダイアログの説明:1つのダイアログに、「本当に実行しますか?」という質問が表示されます。次に、ユーザーからの肯定的な応答でアクションを実行し、ダイアログに結果を表示します。これは確かに非常に一般的な状況であるはずです。
これが私が試したことのいくつかです:
showDialog()の代わりにAlertDialog.show()を使用します。状態(クリックアクションを含む)をonSaveInstanceStateに正常に保存して、onCreateで読み取ります。このようにして、回転後にダイアログが再作成されました。2つのダイアログ、つまり箇条書き2と3を続けて表示することにも問題はありませんでした。しかし、最後のことは機能しませんでした。ウィンドウをリークしないようにするには、onSaveInstanceStateのダイアログを削除する必要がありました(とにかく削除されます)。その後、携帯電話のスクリーンセーバーをアクティブにしてから戻ってきたときに、それを再現する方法が見つかりませんでした。スクリーンセーバーの後に戻るときにどのコードが呼び出されるか知っている人はいますか?テストしたところ、onCreate、onResume、onRestoreInstanceStateなどは呼び出されませんでした。
showDialogメソッドを使用します。これは、箇条書き1と3で正常に機能します。つまり、回転中に状態が保持され(静的ダイアログ参照を使用している場合)、スクリーンセーバーも正しく処理されます。ただし、箇条書き2には問題があります。「ウィンドウがすでにフォーカスされているため、フォーカスゲインを無視して..」という理由で2番目のダイアログがまったく表示されないか、ダイアログが混同されるか、最初のダイアログのアクションがユーザーに確認せずに実行されます。いくつかの問題を示すために、以下のクイックテストコードを作成しました。
エミュレータでこのテストコードを実行し、2番目のダイアログを回転させると、ウィンドウがリークし、最初のダイアログが再び表示されます。
main.xml
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Perform action"
android:onClick="performAction" />
public class ShowDialogTest extends Activity {
private static final int DIALOG_QUESTION = 0;
private static final int DIALOG_INFO = 1;
private static AlertDialog questionDialog;
private static AlertDialog infoDialog;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
public void onResume() {
super.onResume();
showQuestionDialog();
}
/**
* Button click which will bring the dialogs back up.
*/
public void performAction(View v) {
showQuestionDialog();
}
private void showInfoDialog() {
createInfoDialog();
showDialog(DIALOG_INFO);
}
private void showQuestionDialog() {
createQuestionDialog();
showDialog(DIALOG_QUESTION);
}
private void createInfoDialog() {
infoDialog = new AlertDialog.Builder(this).create();
infoDialog.setTitle("The result");
infoDialog.setMessage("Info about the result of the action");
DialogInterface.OnClickListener onClick1 = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
};
infoDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", onClick1);
}
private void createQuestionDialog() {
questionDialog = new AlertDialog.Builder(this).create();
questionDialog.setTitle("A Question");
questionDialog.setMessage("Are you sure?");
DialogInterface.OnClickListener onClick = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// Do something here ..
// Alert the user about the result
showInfoDialog();
}
};
DialogInterface.OnClickListener onCancelClick = new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
};
questionDialog
.setButton(DialogInterface.BUTTON_POSITIVE, "OK", onClick);
questionDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel",
onCancelClick);
}
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_QUESTION:
return questionDialog;
case DIALOG_INFO:
return infoDialog;
}
// Error case (should be handled better ;)
return new Dialog(this);
}
PS。ダイアログの作成メソッドを使用する理由は、アクティビティがダイアログを表示する前に、カスタムテキストとボタンアクションをダイアログに配置する必要があるためです。これはコードには表示されません。DS
他のフォーラムの投稿を読んだり、他のことを試したりしました。新しい問題を作成せずにこれを修正する方法を知っている場合にのみ答えてください。もちろん、コメントに提案を入れることは大歓迎です。
お時間をいただきありがとうございます