Подтвердить что ты не робот

Предотвращение отклонения диалога при повороте экрана в Android

Я пытаюсь запретить отклонения диалогов, построенных с помощью Alert builder, после перезапуска Activity.

Если я перегружаю метод onConfigurationChanged, я могу это сделать успешно и reset макет для исправления ориентации, но я теряю липкую текстовую функцию edittext. Поэтому при решении диалогового вопроса я создал эту проблему edittext.

Если я сохраню строки из edittext и переназначаю их в изменении onCofiguration, они по-прежнему по умолчанию имеют начальное значение, а не то, что было введено перед вращением. Даже если я могу заставить invalidate, похоже, обновить их.

Мне действительно нужно решить либо проблему диалога, либо проблему edittext.

Спасибо за помощь.

4b9b3361

Ответ 1

Лучший способ избежать этой проблемы в настоящее время - использовать DialogFragment.

Создайте новый класс, который расширяет DialogFragment. Переопределите onCreateDialog и верните старый Dialog или AlertDialog.

Затем вы можете показать его с помощью DialogFragment.show(fragmentManager, tag).

Вот пример с Listener:

public class MyDialogFragment extends DialogFragment {

    public interface YesNoListener {
        void onYes();

        void onNo();
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (!(activity instanceof YesNoListener)) {
            throw new ClassCastException(activity.toString() + " must implement YesNoListener");
        }
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new AlertDialog.Builder(getActivity())
                .setTitle(R.string.dialog_my_title)
                .setMessage(R.string.dialog_my_message)
                .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ((YesNoListener) getActivity()).onYes();
                    }
                })
                .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ((YesNoListener) getActivity()).onNo();
                    }
                })
                .create();
    }
}

И в Управлении вы вызываете:

new MyDialogFragment().show(getSupportFragmentManager(), "tag"); // or getFragmentManager() in API 11+

Этот ответ помогает объяснить эти три других вопроса (и их ответы):

Ответ 2

// Prevent dialog dismiss when orientation changes
private static void doKeepDialog(Dialog dialog){
    WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
    lp.copyFrom(dialog.getWindow().getAttributes());
    lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
    lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
    dialog.getWindow().setAttributes(lp);
}
public static void doLogout(final Context context){     
        final AlertDialog dialog = new AlertDialog.Builder(context)
        .setIcon(android.R.drawable.ic_dialog_alert)
        .setTitle(R.string.titlelogout)
        .setMessage(R.string.logoutconfirm)
        .setPositiveButton("Yes", new DialogInterface.OnClickListener()
        {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                ...   
            }

        })
        .setNegativeButton("No", null)      
        .show();    

        doKeepDialog(dialog);
    }

Ответ 3

Если вы меняете макет при изменении ориентации, я бы не поместил android:configChanges="orientation" в ваш манифест, потому что вы все равно воссоздаете представления.

Сохраните текущее состояние вашей активности (например, введенный текст, отображаемый диалог, данные и т.д.), используя следующие методы:

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
}

Таким образом, активность снова проходит через CreateCreate, а затем вызывает метод onRestoreInstanceState, где вы можете снова установить значение EditText.

Если вы хотите хранить более сложные объекты, вы можете использовать

@Override
public Object onRetainNonConfigurationInstance() {
}

Здесь вы можете сохранить любой объект и в onCreate вам просто нужно вызвать getLastNonConfigurationInstance();, чтобы получить объект.

Ответ 4

На этот вопрос был дан ответ давным-давно.

Но это не-хаки и простое решение, которое я использую для себя.

Я сделал этот вспомогательный класс для себя, чтобы вы могли использовать его и в своем приложении.

Использование:

PersistentDialogFragment.newInstance(
        getBaseContext(),
        RC_REQUEST_CODE,
        R.string.message_text,
        R.string.positive_btn_text,
        R.string.negative_btn_text)
        .show(getSupportFragmentManager(), PersistentDialogFragment.TAG);

или

 PersistentDialogFragment.newInstance(
        getBaseContext(),
        RC_EXPLAIN_LOCATION,
        "Dialog title", 
        "Dialog Message", 
        "Positive Button", 
        "Negative Button", 
        false)
    .show(getSupportFragmentManager(), PersistentDialogFragment.TAG);





public class ExampleActivity extends Activity implements PersistentDialogListener{

        @Override
        void onDialogPositiveClicked(int requestCode) {
                switch(requestCode) {
                  case RC_REQUEST_CODE:
                  break;
                }
        }

        @Override
        void onDialogNegativeClicked(int requestCode) {
                switch(requestCode) {
                  case RC_REQUEST_CODE:
                  break;
                }          
        }
}

Ответ 5

Очень простой подход - создать диалоги из метода onCreateDialog() (см. примечание ниже). Вы показываете их через showDialog(). Таким образом, Android обрабатывает вращение для вас, и вам не нужно вызывать dismiss() в onPause(), чтобы избежать WindowLeak, и вам также не нужно восстанавливать диалог. Из документов:

Показать диалог, управляемый этим действием. Вызов onCreateDialog (int, Bundle) будет производиться с тем же идентификатором, когда в первый раз это вызвано для данного идентификатора. После этого диалог будет автоматически сохранен и восстановлен.

Для получения дополнительной информации см. Android docs showDialog(). Надеюсь, это поможет кому-то!

Примечание.. Если вы используете AlertDialog.Builder, не вызывайте show() из onCreateDialog(), тогда вызывайте create(). Если вы используете ProgressDialog, просто создайте объект, задайте нужные параметры и вернете его. В заключение, show() внутри onCreateDialog() вызывает проблемы, просто создайте экземпляр диалогового окна и верните его. Это должно сработать! (У меня возникли проблемы с использованием showDialog() из onCreate(), фактически не отображая диалог, но если вы используете его в onResume() или в обратном вызове прослушивателя, он работает хорошо).

Ответ 6

Вы можете объединить методы Диалог onSave/onRestore с помощью методов Activity onSave/onRestore, чтобы сохранить состояние диалогового окна.

Примечание. Этот метод работает для этих "простых" диалогов, таких как отображение предупреждающего сообщения. Он не будет воспроизводить содержимое WebView, встроенного в диалоговое окно. Если вы действительно хотите предотвратить смещение сложного диалога во время вращения, попробуйте метод Chung IW.

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
     super.onRestoreInstanceState(savedInstanceState);
     myDialog.onRestoreInstanceState(savedInstanceState.getBundle("DIALOG"));
     // Put your codes to retrieve the EditText contents and 
     // assign them to the EditText here.
}

@Override
protected void onSaveInstanceState(Bundle outState) {
     super.onSaveInstanceState(outState);
     // Put your codes to save the EditText contents and put them 
     // to the outState Bundle here.
     outState.putBundle("DIALOG", myDialog.onSaveInstanceState());
}

Ответ 7

Просто добавьте android: configChanges = "ориентация" с вашей деятельностью  в AndroidManifest.xml

Пример:

<activity
            android:name=".YourActivity"
            android:configChanges="orientation"
            android:label="@string/app_name"></activity>

Ответ 8

Просто используйте

ConfigurationChanges = Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.ScreenSize

и приложение будет знать, как обрабатывать вращение и размер экрана.