Я также столкнулся с проблемой, заключающейся в том, что Android не предоставляет встроенного способа проверки вновь введенного значения предпочтения ДО закрытия диалогового окна предпочтений. Проверка, выполненная после закрытия диалогового окна (что выполняет boolean onPreferenceChange
), может только обнаружить, что значение является неправильным и приложение должно предотвратить его сохранение, но это кажется довольно неудобным. Просто представьте, что пользователь сделал опечатку, новое значение не сохраняется, но диалоговое окно закрыто, и пользователю сообщают, что он / она должен повторить процесс с самого начала. Это обязательно должно быть исправлено.
Когда возникает проблема в программировании, лучше предоставить код для решения. Вот почему я публикую ответ с готовым решением для копирования и вставки. Это следует из очевидной идеи из одного из приведенных выше ответов, в то время как в нем не рассматриваются отражения, как подразумевает другой предоставленный фрагмент кода.
public class CustomEditTextPreference extends EditTextPreference
{
// if true, this preference requires new values to be checked for conformance to e-mail syntax
private boolean isEmail = false;
public CustomEditTextPreference(Context context, AttributeSet attrs)
{
super(context, attrs);
// set isEmail either from custom XML-attributes (look up through attrs)
// or just by key
// if(getKey().equals(KNOWN_EMAIL_PREF))
// isEmail = true;
}
/**
* Checks if newValue conforms to a specific rule/syntax.
* Returns error code equal to resource ID of corresponding error message if the value is incorrect,
* or 0 if the validation was successful
*
* @param newValue a string with new preference value that needs a check-up
* @return integer error code equal to error message resource id
*/
private int isValid(String newValue)
{
int result = 0; // no error
if(isEmail)
{
if(!android.util.Patterns.EMAIL_ADDRESS.matcher(newValue).matches())
{
result = R.string.invalid_email;
}
}
// ...
// other check-ups if necessary
return result;
}
@Override
protected void showDialog(Bundle state)
{
super.showDialog(state);
final AlertDialog d = (AlertDialog)getDialog();
final EditText edit = getEditText();
d.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
int errorCode = isValid(edit.getText().toString());
Boolean canCloseDialog = (errorCode == 0);
if(canCloseDialog)
{
d.dismiss();
onDialogClosed(true);
}
else
{
String errorMessage = getContext().getString(errorCode);
Toast t = Toast.makeText(getContext(), errorMessage, Toast.LENGTH_LONG);
t.setGravity(Gravity.CENTER, 0, 0);
t.show();
}
}
});
}
}
Я думаю, что код в значительной степени самоочевиден. Если пользователь заполняет поле с неправильным адресом электронной почты и нажимает кнопку ОК, то диалоговое окно остается открытым, и через тост отображается сообщение об ошибке.