我还遇到了一个问题,即在关闭首选项对话框之前,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();
}
}
});
}
}
我认为代码几乎是不言自明的。如果用户用不正确的电子邮件填写该字段,然后按确定按钮,则对话框保持打开状态并通过 toast 显示错误消息。