Intereting Posts
Скользящее меню (библиотека) всегда в полноэкранном режиме RecyclerView Q & A Как написать код для создания sharedpreferences для массива в android? Почему java.text.DateFormat возвращает тот же формат даты для en_US и en_GB на Android? Как получить мой Android-устройство Внутренний путь к папке Загрузка Как открыть локальный файл pdf в webview в android? Элементы ListView не визуально «подсвечиваются» при выборе в режиме контекстного действия Разрешение API Youtube 403 Запрещенная ошибка Android 5.1.1 и выше – getRunningAppProcesses () возвращает только мой пакет приложений Android UDID, как IPhone? BluetoothHeadset: зачем нужно использовать таймер для вызова startVoiceRecognition? AudioTrack: play () вызван неинициализированным AudioTrack Последнее доступное время любого файла в Android @Named провайдеры с одинаковыми типами возврата в конечном итоге дают java.lang.IllegalArgumentException: дубликат Как получить погоду в текущем местоположении

Предотвращение отклонения DialogFragment при нажатии кнопки

У меня есть DialogFragment с настраиваемым представлением, которое содержит два текстовых поля, в которых пользователь должен ввести свое имя пользователя и пароль. Когда нажата положительная кнопка, я хочу подтвердить, что пользователь действительно ввел что-то, прежде чем отклонять диалог.

public class AuthenticationDialog extends DialogFragment { public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); LayoutInflater inflater = getActivity().getLayoutInflater(); builder.setView(inflater.inflate(R.layout.authentication_dialog, null)) .setPositiveButton(getResources().getString(R.string.login), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // TODO } }) .setNegativeButton(getResources().getString(R.string.reset), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // TODO } }); return builder.create(); } } 

Итак, как я могу предотвратить отклонение диалога? Есть ли какой-то метод, который я должен переопределить?

Solutions Collecting From Web of "Предотвращение отклонения DialogFragment при нажатии кнопки"

Переопределите обработчики кнопок по умолчанию в OnStart (), чтобы сделать это.

 @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setMessage("Test for preventing dialog close"); builder.setPositiveButton("Test", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //Do nothing here because we override this button later to change the close behaviour. //However, we still need this because on older versions of Android unless we //pass a handler the button doesn't get instantiated } }); return builder.create(); } @Override public void onStart() { super.onStart(); //super.onStart() is where dialog.show() is actually called on the underlying dialog, so we have to do it after this point AlertDialog d = (AlertDialog)getDialog(); if(d != null) { Button positiveButton = (Button) d.getButton(Dialog.BUTTON_POSITIVE); positiveButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Boolean wantToCloseDialog = false; //Do stuff, possibly set wantToCloseDialog to true then... if(wantToCloseDialog) dismiss(); //else dialog stays open. Make sure you have an obvious way to close the dialog especially if you set cancellable to false. } }); } } 

См. Мой ответ здесь https://stackoverflow.com/a/15619098/579234 для получения дополнительных пояснений и примеров по другим типам диалогов.

Благодаря Luksprog я смог найти решение.

AuthenticationDialog.java :

 public class AuthenticationDialog extends DialogFragment implements OnClickListener { public interface AuthenticationDialogListener { void onAuthenticationLoginClicked(String username, String password); void onAuthenticationResetClicked(String username); } private AuthenticationDialogListener mListener; private EditText mUsername; private EditText mPassword; private Button mReset; private Button mLogin; public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.authentication_dialog, container); this.getDialog().setTitle(R.string.login_title); mUsername = (EditText) view.findViewById(R.id.username_field); mPassword = (EditText) view.findViewById(R.id.password_field); mReset = (Button) view.findViewById(R.id.reset_button); mLogin = (Button) view.findViewById(R.id.login_button); mReset.setOnClickListener(this); mLogin.setOnClickListener(this); return view; } public void onAttach(Activity activity) { super.onAttach(activity); // Verify that the host activity implements the callback interface try { // Instantiate the NoticeDialogListener so we can send events to the host mListener = (AuthenticationDialogListener) activity; } catch (ClassCastException e) { // The activity doesn't implement the interface, throw exception throw new ClassCastException(activity.toString() + " must implement AuthenticationDialogListener"); } } public void onClick(View v) { if (v.equals(mLogin)) { if (mUsername.getText().toString().length() < 1 || !mUsername.getText().toString().contains("@")) { Toast.makeText(getActivity(), R.string.invalid_email, Toast.LENGTH_SHORT).show(); return; } else if (mPassword.getText().toString().length() < 1) { Toast.makeText(getActivity(), R.string.invalid_password, Toast.LENGTH_SHORT).show(); return; } else { mListener.onAuthenticationLoginClicked(mUsername.getText().toString(), mPassword.getText().toString()); this.dismiss(); } } else if (v.equals(mReset)) { mListener.onAuthenticationResetClicked(mUsername.getText().toString()); } } } 

Authentication_dialog.xml :

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <EditText android:id="@+id/username_field" android:inputType="textEmailAddress" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_marginLeft="4dp" android:layout_marginRight="4dp" android:layout_marginBottom="4dp" android:hint="@string/username" /> <EditText android:id="@+id/password_field" android:inputType="textPassword" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:layout_marginLeft="4dp" android:layout_marginRight="4dp" android:layout_marginBottom="12dp" android:fontFamily="sans-serif" android:hint="@string/password" /> <View android:layout_width="fill_parent" android:layout_height="1dip" android:background="?android:attr/dividerVertical" /> <LinearLayout style="?android:attr/buttonBarStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingTop="0dp" android:measureWithLargestChild="true" > <Button android:id="@+id/reset_button" style="?android:attr/buttonBarButtonStyle" android:layout_height="wrap_content" android:layout_width="0dp" android:layout_weight="1.0" android:text="@string/reset" /> <Button android:id="@+id/login_button" style="?android:attr/buttonBarButtonStyle" android:layout_height="wrap_content" android:layout_width="0dp" android:layout_weight="1.0" android:text="@string/login" /> </LinearLayout> </LinearLayout> в <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <EditText android:id="@+id/username_field" android:inputType="textEmailAddress" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_marginLeft="4dp" android:layout_marginRight="4dp" android:layout_marginBottom="4dp" android:hint="@string/username" /> <EditText android:id="@+id/password_field" android:inputType="textPassword" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:layout_marginLeft="4dp" android:layout_marginRight="4dp" android:layout_marginBottom="12dp" android:fontFamily="sans-serif" android:hint="@string/password" /> <View android:layout_width="fill_parent" android:layout_height="1dip" android:background="?android:attr/dividerVertical" /> <LinearLayout style="?android:attr/buttonBarStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingTop="0dp" android:measureWithLargestChild="true" > <Button android:id="@+id/reset_button" style="?android:attr/buttonBarButtonStyle" android:layout_height="wrap_content" android:layout_width="0dp" android:layout_weight="1.0" android:text="@string/reset" /> <Button android:id="@+id/login_button" style="?android:attr/buttonBarButtonStyle" android:layout_height="wrap_content" android:layout_width="0dp" android:layout_weight="1.0" android:text="@string/login" /> </LinearLayout> </LinearLayout> 

Это решение «sweetspot» как ответов Каракури, так и Соггера. Каракури был на правильном пути, однако вы можете получить эту кнопку только в том случае, если она уже показана (это не так, как указано в комментариях). Вот почему ответ Соггера работает, но я предпочитаю установку в том же методе, что и onCreateDialog , а не в onStart . Решение состоит в том, чтобы обернуть OnShowListener кнопок в OnShowListener диалога.

 public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); // your dialog setup, just leave the OnClick-listeners empty here and use the ones below final AlertDialog dialog = builder.create(); dialog.setOnShowListener(new DialogInterface.OnShowListener() { @Override public void onShow(final DialogInterface dialog) { Button positiveButton = ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE); positiveButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View v) { // TODO - call 'dismiss()' only if you need it } }); Button negativeButton = ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_NEGATIVE); // same for negative (and/or neutral) button if required } }); return dialog; } 

Вы могли бы снова открыть диалог. Или вы можете оставить положительную кнопку отключенной, пока в обоих полях не будет ввода. Это достаточно легко, если вы создаете макет в onCreateVew() . Если вместо этого вы используете класс AlertDialog.Builder , вы можете получить дескриптор кнопки:

 AlertDialog.Builder builder = new AlertDialog.Builder(context); /* ... */ Dialog dialog = builder.create(); Button positiveButton = ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE); /* now you can affect the button */