我也面臨這個問題,即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();
}
}
});
}
}
我覺得代碼非常自我解釋。如果用戶使用不正確的電子郵件填寫該字段,並按下確定按鈕,則該對話框保持打開狀態,並通過吐司顯示錯誤消息。
裏面我沒有看到應該是這樣的,onCreateDialogView和onPrepareDialogBuilder太早對話剛剛建立,因此空,的onClick是爲時已晚,因爲按鈕點擊發生。我錯過了什麼嗎? – 2012-04-02 14:56:35
@peter_budo:如果沒有別的,你會錯過我第二段的前11個單詞:「我唯一能想到的就是你可以嘗試」。我從來沒有試圖在「DialogPreference」上進行驗證。然而,'onBindDialogView()和'showDialog()'似乎是值得嘗試的候選人。 – CommonsWare 2012-04-02 15:18:17
我看到了,我只是試圖獲得一些合理的用戶體驗(至少對我來說),因爲我相信只是提供來自英國或美國等國家的ListView或Spinner用戶會恨我,因爲這些用戶在某處230多個國家的名單結束。 – 2012-04-02 15:29:12