2012-04-01 3 views
2

PreferenceActivity에서 AutoCompliteTextView가 필요하므로 DialogPreference를 확장했습니다. 내 자동 완성 기능은 사용자가 국가 이름을 입력하는 것을 (돕는) 기대하고 있습니다. 사용자가 Cancel을 누르거나 값을 입력하지 않아도 괜찮습니다. 그러나 대화 상자가 닫히기 전에 적절한 이름이 입력되었는지 확인하고 싶습니다. 나는 사용자가 대화 상자를 닫고, 대화 버튼을 클릭하면 onDialogClosed조건을 충족시키지 못하면 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); 
     } 
    }


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

답변

3

를 온 클릭을 무시했는데, 당신이 그것을 중지 할 수있는 일은 없습니다. 난 당신이 시도 할 수있는 생각할 수

있는 유일한 방법은 DialogPreferencegetDialog()를 호출하는 것입니다, AlertDialog에 다음 입력이 유효 할 때 나중에 수 있도록 긍정적 버튼을 검색 할 수 getButton()를 호출하고 사용하지 않는 것이 캐스팅.

+0

어디서이 작업을 수행해야하는지 알지 못합니다. onCreateDialogView와 onPrepareDialogBuilder가 너무 일찍 대화 상자가 빌드되므로 널 클릭이 너무 늦었습니다. 내가 놓친 게 있니? –

+0

@peter_budo : 그 밖의 것이 없다면 두 번째 단락의 처음 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

또한 안드로이드 기본 설정 대화 상자가 닫히기 전에 새로 입력 기본 설정 값을 확인하는 기본 방법을 제공하지 않는 문제에 직면했다. 대화 상자가 닫힌 후 수행되는 점검 (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(); 
     } 
     } 
    }); 
    } 
} 

나는 코드가 꽤 많이 설명한다고 생각한다. 사용자가 잘못된 전자 메일로 필드를 채운 다음 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

당신은 onPrepareDialogBuilder을 대체 할 수있다() DialogPreference 안에

관련 문제