2012-04-01 28 views
2

PreferenceActivityでAutoCompliteTextViewが必要なため、DialogPreferenceを拡張しました。私のオートコンプリートは、ユーザーが国名を入力するのを(助けて)期待しています。キャンセルを押すか値を入力しなくても問題ありませんが、ダイアログが閉じられる前に正しい名前が入力されていることを確認したいと思います。私は、ユーザーがダイアログを閉じて、ダイアログのボタンをクリックするとonDialogClosedDialogPreference onClickを終了しない条件が満たされない場合

でも


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

として


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

答えて

3

をonClickのを上書きしようとした、そしてあなたはそれを止めるためにできることは何もありません。私はあなたが試みることができることを考えることができ

唯一のことは、DialogPreferencegetDialog()を呼び出すことで、AlertDialogに、入力が有効であるとき、後でそれを有効にする、あなたの肯定ボタンを取得するためにgetButton()を呼び出して、それを無効にすることをキャスト。

+0

内部の私はこれが行われるべき場所、onCreateDialogViewとonPrepareDialogBu​​ilderが早すぎる、onClickのが遅すぎるボタンのクリックが起こるので、あるだけのため、ヌル構築されるダイアログのとおりです表示されません。何か不足していますか? –

+0

@peter_budo:何もない場合、あなたは私の2番目の段落の最初の11個の言葉が欠落している:「私はあなたが試みることができることを考えることができる唯一の事」。私は 'DialogPreference'にバリデーションを試みたことはありません。しかし、 'onBindDialogView()と' showDialog() 'は試してみる価値のある候補のようです。 – CommonsWare

+0

英国や米国などの国からListViewやSpinnerユーザーを提供するだけで、私が嫌いになると思うので、私はそれを見ました。 230以上の国の長いリストの終わり。 –

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

8

私はまた、設定ダイアログが閉じられる前に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ボタンを押した場合、ダイアログは開いたままとエラーメッセージがトーストを経由して示されています。

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

関連する問題