android — Предотвращение закрытия диалога при повороте экрана в Android" />

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

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

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

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

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

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

84 голоса | спросил draksia 26 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 26 Sep 2011 19:14:17 +0400 2011, 19:14:17

10 ответов


0

В настоящее время лучший способ избежать этой проблемы - использовать 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+

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

ответил Brais Gabin 31 MarpmSun, 31 Mar 2013 17:19:28 +04002013-03-31T17:19:28+04:0005 2013, 17:19:28
0
// 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);
    }
ответил Chung IW 5 FriEurope/Moscow2014-12-05T10:51:07+03:00Europe/Moscow12bEurope/MoscowFri, 05 Dec 2014 10:51:07 +0300 2014, 10:51:07
0

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

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

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

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

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

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

@Override
public Object onRetainNonConfigurationInstance() {
}

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

ответил Maria Neumayer 26 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 26 Sep 2011 20:45:05 +0400 2011, 20:45:05
0

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

Пример:

<activity
            android:name=".YourActivity"
            android:configChanges="orientation"
            android:label="@string/app_name"></activity>
ответил SAAM 27 J0000006Europe/Moscow 2016, 08:43:11
0

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

  

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

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

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

ответил Caumons 6 FebruaryEurope/MoscowbMon, 06 Feb 2012 02:29:02 +0400000000amMon, 06 Feb 2012 02:29:02 +040012 2012, 02:29:02
0

На этот вопрос давно ответили.

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

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

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

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;
                }          
        }
}
ответил Ioane Sharvadze 23 J0000006Europe/Moscow 2016, 16:00:10
0

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

Примечание. . Этот метод работает для таких "простых" диалогов, как отображение сообщения с предупреждением. Он не будет воспроизводить содержимое 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());
}
ответил hackjutsu 4 FebruaryEurope/MoscowbWed, 04 Feb 2015 02:57:48 +0300000000amWed, 04 Feb 2015 02:57:48 +030015 2015, 02:57:48
0

Похоже, что это все еще проблема, даже если "все делать правильно" и использовать DialogFragment и т. д.

На теме отслеживания проблем Google есть ветка, в которой утверждается, что отклонить сообщение, оставленное в очереди сообщений. Предложенный обходной путь довольно прост:

    @Override
    public void onDestroyView() {
        /* Bugfix: https://issuetracker.google.com/issues/36929400 */
        if (getDialog() != null && getRetainInstance())
            getDialog().setDismissMessage(null);

        super.onDestroyView();
    }

Невероятно, что это все еще необходимо через 7 лет после того, как об этой проблеме впервые сообщили.

ответил Magnus W 17 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 17 Sep 2018 22:35:57 +0300 2018, 22:35:57
0

У меня была похожая проблема: при изменении ориентации экрана вызывался прослушиватель onDismiss, даже если пользователь не отклонил диалог. Я смог обойти эту проблему, используя вместо этого прослушиватель onCancel, который срабатывал как при нажатии кнопки «Назад», так и при касании пользователя. вне диалога.

ответил Sam 30 Jam1000000amTue, 30 Jan 2018 11:28:02 +030018 2018, 11:28:02
0

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

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

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

ответил user3384694 2 FriEurope/Moscow2016-12-02T20:26:47+03:00Europe/Moscow12bEurope/MoscowFri, 02 Dec 2016 20:26:47 +0300 2016, 20:26:47

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132