У меня есть DialogPreference (точнее, EditTextPreference) и я хочу выполнить некоторые проверки значения, введенного пользователем. Эти проверки должны выполняться, когда пользователь нажимает «ОК», а не когда он печатает. Если все в порядке, диалог закроется. Если есть ошибка, должен появиться AlertDialog с объяснением, что не так, и кнопкой ОК. Этот AlertDialog должен появиться «поверх» диалогового окна DialogPreference, и когда нажата кнопка «ОК», первый диалог должен появиться снова.
Я попытался расширить EditTextPreference и переопределить метод onClick (диалоговое окно DialogInterface, int which), чтобы сделать это:
@Override
public void onClick(DialogInterface dialog, int which) {
boolean invalidData = false;
// check input
if (true) {
invalidData = true;
}
if (which == DialogInterface.BUTTON_POSITIVE && invalidData) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setMessage("Some message.")
.setCancelable(false)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
}).create().show();
//super.showDialog(new Bundle());
} else {
super.onClick(dialog, which);
}
}
Но это не дает желаемого эффекта:
- С кодом выше, AlertDialog отображается, а значение не
сохраняется при нажатии положительной кнопки EditTextPreference, но
диалоговое окно EditTextPreference немедленно закрывается.
- Если super.showDialog (new Bundle ()); не комментируется, AlertDialog
и над ним сразу же отображается также EditTextPreference
снова появится диалоговое окно.
Так, как я могу достичь желаемого поведения?
РЕДАКТИРОВАТЬ: Поскольку в соответствии с hackbod это не возможно, я буду использовать решение, которое приближается. Это далеко от хорошего пользовательского опыта, но так как моим приложением будут пользоваться менее 100 человек, и я разрабатываю это в свободное время, я не хочу вкладывать в это слишком много усилий - например, создание собственной DialogPreference. Вот что я сейчас использую:
public abstract class EditTextPreferenceWithCheck extends EditTextPreference {
private boolean mAlertDialogActive;
private String mCachedValue;
private String mMessage = "";
public EditTextPreferenceWithCheck(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public EditTextPreferenceWithCheck(Context context, AttributeSet attrs) {
super(context, attrs);
}
public EditTextPreferenceWithCheck(Context context) {
super(context);
}
/**
* Sets the message that will be shown if inputIsValid(String input) returns
* false.
*
* @param message The message to show
*/
protected void setMessage(String message) {
this.mMessage = message;
}
/**
* Checks if the user input is valid. If not, the message set with
* setMessage(String message) will be shown.
*
* @param input Current value in the text field
* @return true if the current value in the text field is valid, otherwise
* false
*/
protected abstract boolean inputIsValid(String input);
@Override
public void onClick(DialogInterface dialog, int which) {
if (mAlertDialogActive) {
mAlertDialogActive = false;
showDialog(new Bundle());
getEditText().setText(mCachedValue);
} else {
if (which == DialogInterface.BUTTON_POSITIVE
&& !inputIsValid(getEditText().getText().toString())) {
mAlertDialogActive = true;
mCachedValue = getEditText().getText().toString();
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setMessage(mMessage)
.setCancelable(false)
.setPositiveButton(android.R.string.ok, this).show();
} else {
super.onClick(dialog, which);
}
}
}
}