TL; DR - Фрагменты диалогового окна Android по умолчанию закрываются, когда пользователь нажимает любую кнопку или параметр списка в них. Чтобы предотвратить это, вам нужно переопределить метод onDismiss () и продолжить работу по умолчанию, только если пользователь ввел правильные учетные данные.
Согласно официальной документации Android по фрагментам диалогов,
Когда пользователь касается любой из кнопок действий, созданных с помощью AlertDialog.Builder, система закрывает этот диалог для вас.
Система также закрывает диалоговое окно, когда пользователь касается элемента в диалоговом списке, за исключением случаев, когда в списке используются радиокнопки или флажки. В противном случае вы можете вручную закрыть свое диалоговое окно, вызвав dismiss () для вашего DialogFragment.
Если вам нужно выполнить определенные действия, когда диалоговое окно исчезнет, вы можете реализовать метод onDismiss () в вашем DialogFragment.
Вы также можете отменить диалог. Это специальное событие, которое указывает, что пользователь явно покинул диалоговое окно, не выполнив задачу. Это происходит, если пользователь нажимает кнопку «Назад», касается экрана за пределами области диалога или если вы явно вызываете метод cancel () в диалоговом окне (например, в ответ на кнопку «Отмена» в диалоговом окне).
Как показано в примере выше, вы можете ответить на событие отмены, реализовав onCancel () в своем классе DialogFragment.
Таким образом, вы должны проверить правильность учетных данных вашего пользователя в listener.onDialogPositiveClick() метод. Затем вы должны обновить логическое значение, скажем hasUserEnteredCorrectCredentials
, до true. Затем вы должны переопределить onDismiss () и позволить ему закрыть диалоговое окно, только если hasUserEnteredCorrectCredentials
равно true
, в противном случае оставьте диалоговое окно открытым и покажите пользователю ошибку.
Помните, вам нужно будет найтиспособ обновить логическое значение hasUserEnteredCorrectCredentials
с того места, где вы переопределяете метод интерфейса.
Так ваш код станет -
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatDialogFragment;
public class SignInDialogFragment extends AppCompatDialogFragment {
// Use this instance of the interface to deliver action events
private SignInDialogListener listener;
// This boolean checks whether the credentials are correctly entered
private boolean hasUserEnteredCorrectCredentials = false;
// Called when the dialog fragment is created.
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Initialise an alert dialog builder
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the activity's default layout inflater to inflate the dialog fragment
LayoutInflater inflater = requireActivity().getLayoutInflater();
// Set the view to the inflated fragment
builder.setView(inflater.inflate(R.layout.dialog_signin, null))
// Set the positive button's text and onClickListener
.setPositiveButton("Sign in", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
// Send the positive button event back to the host activity
// TODO - Find a way to set hasUserEnteredCorrectCredentials to true if the credentials are correct.
listener.onDialogPositiveClick(SignInDialogFragment.this);
}
})
// Set the positive button's text and onClickListener
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
// Cancel the dialog
SignInDialogFragment.this.getDialog().cancel();
}
});
// Return the created dialog to the host activity
return builder.create();
}
// Interface to manage clicks on the dialog's buttons
public interface SignInDialogListener {
// ClickListener for the positive button
void onDialogPositiveClick(SignInDialogFragment dialog);
}
// Override the Fragment.onAttach() method to instantiate the SignInDialogListener
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
// Verify that the host activity implements the callback interface
try {
// Instantiate the NoticeDialogListener so we can send events to the host
listener = (SignInDialogListener) context;
} catch (ClassCastException e) {
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(context.toString()
+ " must implement SignInDialogListener");
}
}
// Called when the user clicks a button, or when the user selects an option in a list dialog
@Override
public void onDismiss(@NonNull DialogInterface dialog) {
// Dismiss the dialog only if the user has entered correct credentials
if (hasUserEnteredCorrectCredentials) {
super.onDismiss(dialog);
}
}
}
Надеюсь, это поможет!