12

我有一个从菜单选项启动的工作首选项设置。在首选项中,我设置了一个自定义首选项,它必须启动一个带有 3 个 TextView 的对话框来设置确认和更改密码。现在我不知道如何从 PreferenceActivity 的 onPreferenceClick 启动对话框。如果我听起来像个新手——我是,对不起!

这是我的对话框弹出的xml布局:

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:id="@+id/root"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <TextView
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:id="@+id/TextView_Pwd1"
        android:text="@string/settings_oldpassword"
        android:textStyle="bold" />

    <EditText
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:id="@+id/EditText_OldPwd" />

    <TextView
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:id="@+id/TextView_Pwd1"
        android:text="@string/settings_password"
        android:textStyle="bold" />

    <EditText
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:id="@+id/EditText_Pwd1"
        android:inputType="textPassword" />

    <TextView
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:id="@+id/TextView_Pwd2"
        android:text="@string/settings_password2"
        android:textStyle="bold" />

    <EditText
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:id="@+id/EditText_Pwd2"
        android:inputType="textPassword" />

    <TextView
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:id="@+id/TextView_PwdProblem"
        android:textStyle="bold"
        android:gravity="center" />

    <TextView
        android:id="@+id/TextView_PwdProblem"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="@string/settings_pwd_not_equal" />

    <CheckBox
        android:id="@+id/checkShowPwdText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/settings_showpwd_text" />

这是对话框弹出窗口的 DialogChangePassword 类:

package biz.linsys.package;

import android.app.Dialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.DialogPreference;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

public class DialogChangePassword extends DialogPreference {

    private String strPass1;
    private String strPass2;

    public DialogChangePassword(Context context, AttributeSet attrs) {
        super(context, attrs);
        setDialogLayoutResource(R.layout.dialog_pwdchange);
    }

    @Override
     protected void onBindDialogView(View view) {

        Dialog pwdDialog            = getDialog();
        final EditText password1    = (EditText) pwdDialog.findViewById(R.id.EditText_Pwd1);
        final EditText password2    = (EditText) pwdDialog.findViewById(R.id.EditText_Pwd2);
        final TextView error        = (TextView) pwdDialog.findViewById(R.id.TextView_PwdProblem);      

        password2.addTextChangedListener(new TextWatcher() {

            @Override
            public void afterTextChanged(Editable s) {

                strPass1 = password1.getText().toString();
                strPass2 = password2.getText().toString();

                if (strPass1.equals(strPass2)) {

                    error.setText(R.string.settings_pwd_equal);
                } else {

                    error.setText(R.string.settings_pwd_not_equal);
                }
            }  public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
               public void onTextChanged(CharSequence s, int start, int before, int count) {}
        });

        super.onBindDialogView(view);

    }

    @Override
    protected void onDialogClosed(boolean positiveResult) {

        if(!positiveResult) return;

        SharedPreferences.Editor editor = getEditor();

        if (strPass1.equals(strPass2)) {

            editor.putString("password", strPass1);
            editor.commit();
        }

        super.onDialogClosed(positiveResult);

    }
}

这是包含自定义首选项 onPreferenceClick 的 PreferenceActivity 类。这是我需要调用对话框来更改用户密码设置的地方。

package biz.linsys.package;

import android.content.Context;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;

public class Preferences extends PreferenceActivity {

    public static Context dialogContext;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);

        // Get the custom preference
        Preference customPref = (Preference) findPreference("customPref");

        customPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {

            public boolean onPreferenceClick(Preference preference) {

                // [ NEED TO CALL DIALOG FROM HERE ]

                return false;
           }
        });
    }
}
4

1 回答 1

13

这是文档中缺少的东西,我发现了很多类似的问题,大部分都没有明确的答案。我今天遇到了同样的问题,不知何故我找到了解决方案,所以我将在这里总结我的任务,希望有人会觉得这很有用。顺便说一句,您的问题是最详细和最准确的。

一般的一点是您不需要手动创建对话框,您只需 1)创建 DialogPreference 的子类,它将处理复杂首选项的逻辑,以及 2)在您的 preferences.xml 中创建正确类型的节点所以对话框将自动生成。

Android SDK 的问题是您无法使用可视 XML 编辑器添加正确的节点,您需要手动编辑文件。

文档的问题在于它错过了这一点信息。

所以这里是一步一步的解决方案:

1) 创建一个 DialogPreference 的子类来处理您的特殊偏好。有关您的子类所需内容的详细信息,我建议您使用此答案

2) 在您的preferences.xml 中创建一个Preference 节点。

3) 编辑preferences.xml 并将Preference 替换为DialogPreference 子类的全名,包括包路径,例如com.sample.MyPreferenceDialog。您还可以向节点添加一些属性以自定义对话框(标题、图标等),有关详细信息,请参阅此答案或 DialogPreference 的文档。

就这样。您不需要将 OnPreferenceClickListener 添加到首选项中,对话框将自动显示。

注意:我不是 100% 确定这是使用事物的预期方式,但它似乎正在工作。

于 2012-09-21T16:21:34.200 回答