Как заставить PreferenceActivity запускать диалог, чтобы установить пользовательское предпочтение

У меня есть рабочая настройка Preferences, запущенная из пункта меню. В настройках я установил пользовательскую настройку, которая должна запускать диалоговое окно с 3 TextViews, чтобы установить подтверждение и изменить пароль. Теперь я не знаю, как запустить диалог из onPreferenceClick PreferenceActivity. Если я звучу как новичок - да, извините!

Вот мой макет 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);

    }
}

Это класс PreferenceActivity, содержащий пользовательское предпочтение onPreferenceClick. Здесь мне нужно вызвать диалоговое окно, чтобы изменить настройку пароля пользователя.

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;
           }
        });
    }
}

person Lukuluba    schedule 04.04.2012    source источник
comment
Итак, у вас есть активность предпочтений, при нажатии на которую запускается диалоговое окно с кнопками?   -  person Jared Burrows    schedule 05.04.2012
comment
@MasterJB: Да, в диалоговом окне есть кнопки. Я понимаю, что не включил кнопки в файл макета XML.   -  person Lukuluba    schedule 05.04.2012
comment
Ну, я спросил об этом, потому что в прошлом я просто запускал небольшую активность с помощью кнопки с графическим интерфейсом диалога, который был настроен из файла manifest:android:theme=@android:style/Theme.Dialog. Вы бы сделали это, просто намереваясь совершить действие, и остроумие появится в диалоге.   -  person Jared Burrows    schedule 05.04.2012


Ответы (1)


Это то, чего не хватает в документации, и я нашел много подобных вопросов по этому поводу, в основном без определенных ответов. Сегодня я столкнулся с той же проблемой и каким-то образом нашел решение, поэтому я подытожу здесь свои поиски в надежде, что кто-то найдет это полезным. Кстати, ваш вопрос самый подробный и точный среди других.

Общий смысл заключается в том, что вам не нужно создавать диалог вручную, вы просто 1) создаете подкласс DialogPreference, который будет обрабатывать логику сложного предпочтения, и 2) создаете узел соответствующего типа в файле preferences.xml. поэтому диалог будет создан автоматически.

Проблема Android SDK заключается в том, что вы не можете добавить нужный узел с помощью визуального XML-редактора, вам нужно пойти и отредактировать файл вручную.

Проблема документации в том, что она упускает эту самую часть информации.

Итак, вот пошаговое решение:

1) Создайте подкласс DialogPreference, который будет обрабатывать ваши особые предпочтения. Для получения подробной информации о том, что необходимо в вашем подклассе, я бы рекомендовал этот ответ.

2) Создайте узел Preference в файле settings.xml.

3) Отредактируйте файл preferences.xml и замените Preference полным именем вашего подкласса DialogPreference, включая путь к пакету, например. г. com.sample.MyPreferenceDialog. Вы также можете добавить к узлу некоторые атрибуты для настройки диалогового окна (заголовок, значок и т. д.), см. этот ответ или документацию для DialogPreference для деталей.

Это все. Вам не нужно добавлять OnPreferenceClickListener в настройки, диалоговое окно появится автоматически.

Примечание. Я не уверен на 100%, что это предполагаемый способ использования вещей, но, похоже, он работает.

person Alexander Dunaev    schedule 21.09.2012