У меня есть диалог с EditText
для ввода. Когда я нажимаю кнопку «Да» в диалоговом окне, он проверяет ввод, а затем закрывает диалоговое окно. Однако, если ввод неправильный, я хочу остаться в том же диалоге. Каждый раз, независимо от того, что ввод, диалог должен автоматически закрываться, когда я нажимаю кнопку «нет». Как я могу отключить это? Кстати, я использовал PositiveButton и NegativeButton для кнопки в диалоге.
732
Вот некоторые решения для всех типов диалогов, включая решение для AlertDialog.Builder, которое будет работать на всех уровнях API (работает ниже API 8, а другой ответ здесь нет). Существуют решения для AlertDialogs, использующие AlertDialog.Builder, DialogFragment и DialogPreference.
Ниже приведены примеры кода, показывающие, как переопределить стандартный обработчик общих кнопок и предотвратить закрытие диалога для этих различных форм диалогов. Все примеры показывают, как предотвратить закрытие диалогового окна положительной кнопкой.
Примечание: описание того, как закрытие диалога работает под капотом для базовых классов Android и почему выбраны следующие подходы, следует после примеров для тех, кто хочет получить больше информации
AlertDialog.Builder - Изменить обработчик кнопки по умолчанию сразу после show ()
DialogFragment - переопределить onResume ()
DialogPreference - переопределить showDialog ()
Объяснение подходов:
источник
ProgressDialog
при нажатии на кнопку?Альтернативное решение
Я хотел бы представить альтернативный ответ с точки зрения UX.
Почему вы хотите запретить закрытие диалогового окна при нажатии кнопки? Предположительно, это потому, что у вас есть пользовательский диалог, в котором пользователь не сделал выбор или еще не полностью заполнил все. И если они не закончены, то вы не должны позволять им нажимать на положительную кнопку вообще. Просто отключите его, пока все не будет готово.
Другие ответы здесь дают много приемов для переопределения положительного нажатия кнопки. Если бы это было важно сделать, разве Android не сделал бы удобный способ сделать это? Они не
Вместо этого в руководстве по разработке Dialogs приведен пример такой ситуации. Кнопка ОК отключена, пока пользователь не сделает выбор. Никаких главных трюков не требуется вообще. Для пользователя очевидно, что что-то еще нужно сделать, прежде чем продолжать.
Как отключить положительную кнопку
См. Документацию по Android для создания пользовательского макета диалога . Он рекомендует вам разместить
AlertDialog
внутриDialogFragment
. Затем все, что вам нужно сделать, это настроить слушателей на элементы макета, чтобы знать, когда включать или отключать положительную кнопку.EditText
, то используйте TextWatcher .Положительную кнопку можно отключить так:
Вот вся работа
DialogFragment
с отключенной положительной кнопкой, которая может использоваться на изображении выше.Пользовательский диалог может быть запущен из действия, подобного этому:
Ноты
Кнопка все еще
null
включена,onCreateDialog
поэтому я отключил ееonResume
. Это приводит к нежелательному эффекту его повторного отключения, если пользователь переключается на другое приложение и затем возвращается, не закрывая диалоговое окно. Эту проблему можно решить, отменив выбор любого пользователя или вызвав командуRunnable
from,onCreateDialog
чтобы отключить кнопку в следующем цикле выполнения.связанные с
источник
Я написал простой класс (AlertDialogBuilder), который можно использовать, чтобы отключить функцию автоматического закрытия при нажатии кнопок диалогового окна.
Он также совместим с Android 1.6, поэтому он не использует OnShowListener (который доступен только API> = 8).
Таким образом, вместо использования AlertDialog.Builder вы можете использовать этот CustomAlertDialogBuilder. Наиболее важной частью является то, что вы не должны вызывать create () , а только метод show () . Я добавил методы, такие как setCanceledOnTouchOutside () и setOnDismissListener, так что вы все равно можете установить их непосредственно в компоновщике.
Я тестировал его на Android 1.6, 2.x, 3.x и 4.x, поэтому он должен работать довольно хорошо. Если вы обнаружите какие-либо проблемы, пожалуйста, прокомментируйте здесь.
РЕДАКТИРОВАТЬ Вот небольшой пример того, как использовать CustomAlertDialogBuilder:
Ура,
Yuvi
источник
Context mContext
и установите его в конструкторе.Вот кое-что, если вы используете
DialogFragment
- который в любом случае является рекомендуемым способом обработки диалогов.Что происходит с
setButton()
методом AlertDialog (и я представляю то же самое сAlertDialogBuilder
ssetPositiveButton()
иsetNegativeButton()
), так это то, что кнопка, которую вы установили (напримерAlertDialog.BUTTON_POSITIVE
) с помощью нее, фактически вызовет ДВА различныхOnClickListener
объекта при нажатии.Первое существо DialogInterface.OnClickListener , которая является параметром
setButton()
,setPositiveButton()
иsetNegativeButton()
.Другой - это View.OnClickListener , который будет автоматически отключать вас
AlertDialog
при нажатии любой из его кнопок - и устанавливаетсяAlertDialog
сам по себе.Что вы можете сделать , это использовать
setButton()
сnull
какDialogInterface.OnClickListener
, чтобы создать кнопку, а затем вызвать пользовательский метод действия внутриView.OnClickListener
. Например,Затем вы можете переопределить
AlertDialog
кнопки по умолчаниюView.OnClickListener
(которые в противном случае закрыли бы диалог) в методеDialogFragment
sonResume()
:Вам нужно будет установить это в
onResume()
методе, потому что онgetButton()
будет возвращатьсяnull
до тех пор, пока не будет показано диалоговое окно!Это должно привести к тому, что ваш метод пользовательского действия будет вызываться только один раз, и диалоговое окно по умолчанию не будет закрыто.
источник
Вдохновленный ответом Тома, я думаю, что идея здесь такова:
onClickListener
во время создания диалогаnull
onClickListener
после того, как диалоговое окно отображается.Вы можете переопределить
onShowListener
как Том. В качестве альтернативы вы можетеshow()
onClickListener
следующим образом (я думаю, что они немного более читабельны).Код:
источник
Для предварительного API 8 я решил проблему, используя логический флаг, прослушиватель dismiss и снова вызвал dialog.show, если в случае содержимое editText было неправильным. Нравится:
источник
Ответ по этой ссылке - простое решение, которое совместимо прямо с API 3. Оно очень похоже на решение Тома Боллвитта, но без использования менее совместимого OnShowListener.
Я сделал небольшие изменения в коде Kamen, так как я расширял EditTextPreference.
Так весело!
источник
Этот код будет работать для вас, потому что у меня была схожая проблема, и это сработало для меня. :)
1. Переопределите метод Onstart () в вашем классе фрагмента диалога.
источник
Для ProgressDialogs
Чтобы предотвратить автоматическое закрытие диалога, вы должны установить
OnClickListener
после тогоProgressDialog
, как отображается, например:источник
источник
Вы можете добавить builder.show (); после проверки сообщения до возврата;
нравится
источник
Чтобы диалоговое окно не закрывалось при нажатии, оно должно закрываться только при наличии Интернета
Я пытаюсь сделать то же самое, поскольку я не хочу, чтобы диалоговое окно было закрыто до тех пор, пока интернет не подключен.
Вот мой код:
А вот мой код диспетчера подключений:
источник
The specified child already has a parent. You must call removeView() on the child's parent first
Если вы используете,
material design
я бы предложил проверить диалоги материалов . Он исправил несколько проблем, связанных с открытыми в данный момент ошибками Android (см. 78088 ), но самое главное для этого тикета -autoDismiss
флаг, который можно установить при использованииBuilder
.источник
Используйте пользовательский макет для вашего
DialogFragment
и добавитьLinearLayout
под содержанием , которое может быть оформлено в стиле безграничного , чтобы соответствовать Google Material Design. Затем найдите вновь созданные кнопки и переопределите ихOnClickListener
.Пример:
dialog_add_topic.xml :
Это конечный результат.
источник
Это может быть построено самым простым способом:
Диалог оповещений с пользовательским видом и двумя кнопками (положительный и отрицательный).
CustomClickLister из Positive Баттона из оповещения Dailog :
Выполнено
источник
Это, вероятно, очень поздний ответ, но использование setCancelable поможет.
источник