2012-04-01 43 views
2

我需要PreferenceActivity中的AutoCompliteTextView,因此我擴展了DialogPreference。我的自動complite期待(幫助)用戶輸入國家名稱。我很好,如果用戶按取消或不輸入任何值,但我想確保在關閉對話框之前輸入正確的名稱。我想一旦用戶點擊一個對話框按鈕,在對話框關閉重寫的onClick作爲如果條件不符合,請勿關閉DialogPreference onClick


@Override 
public void onClick(DialogInterface dialog, int which) { 
     if (!validator.isValid(textView.toString())) { 
      onDialogClosed(false); 
     } else { 
      //do something here 
      super.onClick(dialog, which); 
     } 
    }

也onDialogClosed


@Override 
    protected void onDialogClosed(boolean positiveResult) { 
     if (validator.isValid(textView.toString())) { 
      //do something here 
      super.onDialogClosed(positiveResult); 
     } 
    } 

回答

3

,並沒有什麼可以阻止它這樣做。

我能想到的,你可以嘗試的唯一的事情就是打電話給getDialog()DialogPreference,強制轉換成AlertDialog,然後調用getButton()檢索您的肯定按鈕,並禁用它,使之後來當輸入有效。

+0

裏面我沒有看到應該是這樣的,onCreateDialogView和onPrepareDialogBu​​ilder太早對話剛剛建立,因此空,的onClick是爲時已晚,因爲按鈕點擊發生。我錯過了什麼嗎? – 2012-04-02 14:56:35

+0

@peter_budo:如果沒有別的,你會錯過我第二段的前11個單詞:「我唯一能想到的就是你可以嘗試」。我從來沒有試圖在「DialogPreference」上進行驗證。然而,'onBindDialogView()和'showDialog()'似乎是值得嘗試的候選人。 – CommonsWare 2012-04-02 15:18:17

+0

我看到了,我只是試圖獲得一些合理的用戶體驗(至少對我來說),因爲我相信只是提供來自英國或美國等國家的ListView或Spinner用戶會恨我,因爲這些用戶在某處230多個國家的名單結束。 – 2012-04-02 15:29:12

6

實際上,通過反思,我實現了你所說的。

@Override 
    public void onClick(DialogInterface dialog, int which) { 
     if(!validate(arg)){ 
     try { 
      // do not close 
      Field field = dialog.getClass().getSuperclass() 
        .getDeclaredField("mShowing"); 
      field.setAccessible(true); 
      field.set(dialog, false); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

}

+0

這完全有效! – jmacboy 2013-08-27 17:22:51

8

我也面臨這個問題,即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(); 
     } 
     } 
    }); 
    } 
} 

我覺得代碼非常自我解釋。如果用戶使用不正確的電子郵件填寫該字段,並按下確定按鈕,則該對話框保持打開狀態,並通過吐司顯示錯誤消息。

2

如果你想顯示在對話框中的一些錯誤,而不是禁用按鈕,那麼你需要創建一個擴展EditTextPreference類CustomEditTextPreference

下面

是代碼片段

public class CustomEditTextPreference extends EditTextPreference { 
EditText setPasswordEditText; 
private Context context; 
AlertDialog alertDialog; 

public CustomEditTextPreference(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    this.context = context; 
    setPasswordEditText = this.getEditText(); 
} 

@Override 
protected void showDialog(Bundle state) { 
    super.showDialog(state); 

    alertDialog = (AlertDialog) getDialog(); 
    alertDialog.setCanceledOnTouchOutside(false); 
    Button positiveButton = alertDialog 
      .getButton(AlertDialog.BUTTON_POSITIVE); 
    positiveButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      String str = setPasswordEditText.getText().toString(); 
      if (/*condition not met*/) { 
       showError(); 
      } else { 
       alertDialog.dismiss(); 
      } 

     } 
    }); 

} 
1

可以覆蓋onPrepareDialogBu​​ilder ()的DialogPreference