Восстановление диалога после поворота экрана - PullRequest
0 голосов
/ 29 мая 2018

Я испытываю более мелкую проблему, чем что-либо еще, пытаясь восстановить диалоговое окно с ошибкой в ​​действии во время поворота экрана (портрет в альбомной ориентации или наоборот).Диалоговое окно отображается правильно при возникновении ошибки, но при повороте экрана диалоговое окно восстанавливается неправильно.Вместо этого весь экран становится тусклым, но ничего не видно.Вот соответствующий код:

private void showErrorDialog() {
    // assume hasErrorDialog is true at this point
    AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(SomeActivity.this);
    LayoutInflater inflater = SomeActivity.this.getLayoutInflater();
    View dialogView = inflater.inflate(R.layout.dialog_alert, null);
    dialogBuilder.setView(dialogView);
    TextView msgText = (TextView) dialogView.findViewById(R.id.alertMessageText);
    msgText.setText("something went wrong");
    Button okButton = (Button) dialogView.findViewById(R.id.alertOkButton);
    okButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {
            alertDialog.dismiss();
            hasErrorDialog = false;
        }
    });

    alertDialog = dialogBuilder.create();
    alertDialog.show();
    RelativeLayout rl = (RelativeLayout) findViewById(R.id.someActivity);
    int width = rl.getWidth();
    alertDialog.getWindow().setLayout((int) (0.9 * width), ViewGroup.LayoutParams.WRAP_CONTENT);
}

Когда вышеуказанный метод вызывается после , активность загружается, и возникает ошибка, диалог загружается и ведет себя точно так, как должен.Поэтому приведенный выше код полностью работает при вызове в обычных условиях.

Однако я добавил логику, которая использует сохраненное состояние экземпляра, чтобы попытаться «запомнить», что на самом деле должно быть диалоговое окно с сообщением об ошибке.После поворота я пытаюсь вызвать вышеупомянутый метод снова после проверки этого состояния экземпляра:

protected void onSaveInstanceState(Bundle bundle) {
    super.onSaveInstanceState(bundle);

    bundle.putBoolean("HASERRORDIALOG", hasErrorDialog);
}

Затем в onCreate() Я пытаюсь проверить это состояние, и, если оно присутствует, снова вызвать showErrorDialog():

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.some_activity);

    if (savedInstanceState != null) {
        hasErrorDialog = savedInstanceState.getBoolean("HASERRORDIALOG");

        if (hasErrorDialog) {
            // this does not load the dialog correctly
            showErrorDialog();
        }
    }
}

Большинство вопросов / ответов, которые я читал на Stack Overflow, решают эту проблему, предлагая использовать DialogFragment.Пока я готов идти в этом направлении, мне было интересно, нет ли какого-либо средства для моего текущего кода.

1 Ответ

0 голосов
/ 29 мая 2018

Работая с превосходным комментарием @MikeM, я понял, что проблема заключалась в том, что RelativeLayout моей деятельности еще не был полностью создан в методе onCreate(), и, следовательно, его ширина не соответствовала моим ожиданиям (вероятно,равным нулю).

В качестве обходного пути я использовал getDisplayMetrics() для доступа к фактической ширине устройства, которая все еще существует в точке жизненного цикла, где вызывается onCreate:

alertDialog = dialogBuilder.create();
alertDialog.show();
int width = (int)(getResources().getDisplayMetrics().widthPixels*0.90);
alertDialog.getWindow().setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT);

Урок, который необходимо усвоить, заключается в том, что при создании диалога на основе чего-либо в вашем макете существует потенциальная оговорка.В этом случае при попытке восстановить это диалоговое окно в onCreate после поворота устройства произойдет сбой, но это один из возможных обходных путей.

...