Как сделать PreferenceActivity запустите диалоговое окно, чтобы установить пользовательские настройки
У меня есть рабочая настройка настроек, запущенная из опции меню. В настройках я настроил пользовательское предпочтение, которое должно запустить диалог с 3 текстовыми элементами, чтобы установить подтверждение и изменить пароль. Теперь я не знаю, как запустить диалог из 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);
}
}
Этот класс PreferenceActivity, содержащий Custom Preference 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;
}
});
}
}
Ответы
Ответ 1
Это то, чего не хватает в документации, и я нашел много похожих вопросов по этому поводу, в основном без определенных ответов. Сегодня я столкнулся с такой же проблемой, и каким-то образом я нашел решение, поэтому я подытожу свой запрос здесь, просто в надежде, что кто-то найдет это полезным. Кстати, ваш вопрос является самым подробным и точным среди других.
Общий момент заключается в том, что вам не нужно создавать диалог вручную, вы просто 1) создаете подкласс DialogPreference, который будет обрабатывать логику сложного предпочтения и 2) создать node соответствующего типа в вашем preferences.xml, поэтому диалог будет создан автоматически.
Проблема Android SDK заключается в том, что вы не можете добавить этот правильный node с помощью визуального XML-редактора, вам нужно пойти и отредактировать файл вручную.
Проблема документации заключается в том, что она пропускает этот самый бит информации.
Итак, вот пошаговое решение:
1) Создайте подкласс DialogPreference, который будет обрабатывать ваши особые предпочтения. Подробнее о том, что необходимо в вашем подклассе, я бы рекомендовал этот ответ.
2) Создайте предпочтение node в вашем preferences.xml.
3) Отредактируйте файл preferences.xml и замените Preference с полным именем вашего подкласса DialogPreference, включая путь пакета, e. г. com.sample.MyPreferenceDialog. Вы также можете добавить некоторые атрибуты в node, чтобы настроить диалог (название, значок и т.д.), См. этот ответ или документацию для DialogPreference для деталей.
Это все. Вам не нужно добавлять OnPreferenceClickListener в настройки, диалог будет отображаться автоматически.
Примечание. Я не уверен на 100%, что это предполагаемый способ использования вещей, но, похоже, он работает.