单击“确定”时,在“DialogPreference”上显示“AlertDialog”

时间:2011-07-23 17:58:58

标签: android preferences alertdialog

我有一个DialogPreference(更确切地说是EditTextPreference),并希望对用户输入的值执行一些检查。这些检查应在用户点击确定时进行,而不是在他打字时进行。如果一切正常,对话框将关闭。如果出现错误,将出现AlertDialog,其中包含错误解释和ok按钮。这个AlertDialog将在DialogPreference对话框的“顶部”进入视图,当单击ok按钮时,第一个对话框将再次进入视图。

我尝试扩展EditTextPreference并覆盖onClick(DialogInterface对话框,int which)方法来执行此操作:

@Override
public void onClick(DialogInterface dialog, int which) {
    boolean invalidData = false;
    // check input
    if (true) {
        invalidData = true;
    }
    if (which == DialogInterface.BUTTON_POSITIVE && invalidData) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
        builder.setMessage("Some message.")
        .setCancelable(false)
        .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                dialog.cancel();
            }
        }).create().show();
        //super.showDialog(new Bundle());
    } else {
        super.onClick(dialog, which);
    }
}

但这没有达到预期的效果:

  • 使用上面的代码,会显示AlertDialog,而值则不会 单击EditTextPreference的正按钮时保存,但是 EditTextPreference的对话框立即关闭。
  • 如果是super.showDialog(new Bundle());取消注释,AlertDialog
    显示在它上面,立即显示EditTextPreference的
    对话框再次弹出。

那么我怎样才能达到预期的行为?

编辑:根据hackbod这是不可能的,我将使用一个接近的解决方案。这远不是一个良好的用户体验,但由于我的应用程序将由少于100人使用,我在业余时间开发这个,我不想在其中投入太多精力 - 比如创建我自己的DialogPreference。这就是我现在使用的:

public abstract class EditTextPreferenceWithCheck extends EditTextPreference {

    private boolean mAlertDialogActive;
    private String mCachedValue;
    private String mMessage = "";

    public EditTextPreferenceWithCheck(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public EditTextPreferenceWithCheck(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EditTextPreferenceWithCheck(Context context) {
        super(context);
    }

    /**
     * Sets the message that will be shown if inputIsValid(String input) returns
     * false.
     * 
     * @param message The message to show
     */
    protected void setMessage(String message) {
        this.mMessage = message;
    }

    /**
     * Checks if the user input is valid. If not, the message set with
     * setMessage(String message) will be shown.
     * 
     * @param input Current value in the text field
     * @return true if the current value in the text field is valid, otherwise
     *         false
     */
    protected abstract boolean inputIsValid(String input);

    @Override
    public void onClick(DialogInterface dialog, int which) {
        if (mAlertDialogActive) {
            mAlertDialogActive = false;
            showDialog(new Bundle());
            getEditText().setText(mCachedValue);
        } else {
            if (which == DialogInterface.BUTTON_POSITIVE
                    && !inputIsValid(getEditText().getText().toString())) {
                mAlertDialogActive = true;
                mCachedValue = getEditText().getText().toString();
                AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
                builder.setMessage(mMessage)
                        .setCancelable(false)
                        .setPositiveButton(android.R.string.ok, this).show();
            } else {
                super.onClick(dialog, which);
            }
        }
    }

}

1 个答案:

答案 0 :(得分:1)

抱歉,您无法执行此操作,EditTextPreference会在传递结果时自动关闭其对话框,但您无法阻止它执行此操作。

我建议你制作自己的DialogPreference,在点击时显示你自己的自定义对话框。您可以对该对话框中的文本进行验证,因为它是您自己的对话框。这也将为您提供更好的用户体验。