如果条件不满足,请不要关闭DialogPreference onClick

pet*_*udo 4 android onclick dialog-preference

我需要在PreferenceActivity中使用AutoCompliteTextView,因此我扩展了DialogPreference.我的auto-complite期待(帮助)用户输入国家/地区名称.如果用户按"取消"或没有输入任何值,我会很好,但是我想确保在关闭对话框之前输入正确的名称.我试图覆盖onClick as


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

还有onDialogClosed


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

Sta*_*tan 9

我还遇到了一个问题,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();
        }
      }
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

我认为代码几乎是自我解释的.如果用户使用不正确的电子邮件填写该字段,并按下"确定"按钮,则对话框将保持打开状态,并通过Toast显示错误消息.


wit*_*usk 6

实际上,通过使用reflection,我实现了你所说的.

@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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)