また、設定ダイアログが閉じられる前に、新しく入力された設定値を確認する組み込みの方法が Android に用意されていないという問題にも直面しました。ダイアログが閉じられた後に実行されるチェック ( がboolean onPreferenceChange
達成すること) は、値が正しくないことを発見することしかできず、アプリはそれが保存されないようにする必要がありますが、これはかなり不便に思えます。ユーザーがタイプミスをした場合、新しい値は保存されませんが、ダイアログは閉じられ、プロセスを最初からやり直す必要があることがユーザーに通知されます。きっと直るはずです。
プログラミングで問題が発生した場合は、解決のためのコードを提供することをお勧めします。これが、コピー&ペーストの準備ができたソリューションで回答を投稿する理由です。上記の回答の1つからの明らかなアイデアに従いますが、提供された他のコードスニペットが意味するように反射を処理しません。
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();
}
}
});
}
}
コードはほとんど自明だと思います。ユーザーがフィールドに誤った電子メールを入力して [OK] ボタンを押すと、ダイアログは開いたままになり、トーストを介してエラー メッセージが表示されます。