我已经自定义了我的Android应用程序设置页面,我使用API 21或26。我添加了一个CustomListPreference java类,它继承自ListPreference并将其集成到SettingActivity中。
但是,我重新列出了系统不起作用,因为SettingActivity具有从androidx.preference.PreferenceFragmentCompat继承的Setting片段,并且用于Setting Activity的包如下:
如果我为自定义 ListPreference 使用包 android.preference.Preference 和 android.preference.ListPreference,则当 Android 为设置活动创建对象时,我的所有代码都会停止工作。它在自定义 ListPreference 构造函数之后崩溃,并出现错误“错误膨胀类 com.signatact.doorbell.dialog.preference.AppListPreference”。 深入研究细节,我发现崩溃的原因是为设置活动创建新对象的最后一步是转换为 androidx.preference.Preference:
来自 PreferenceInflater.java:
import androidx.preference;
...
return (Preference) constructor.newInstance(args); // line 242
很明显,系统因在 android.preference.Preference 和 androidx.preference.Preference 之间进行转换而失败。
但是,如果我将自定义 ListPreference 文件实现移至 androidx,几乎所有我之前用于自定义的方法都不可用,这里列出了不可用的方法,我将自定义逻辑放在其中:
// 错误:方法不会覆盖其超类中的方法
@Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder)
...
@Override
protected void onDialogClosed(boolean positiveResult)
看起来 Google 极大地改变了他们的 API,有人能告诉我如何在 AndroidX 中自定义 ListPreference 吗? 一般来说,我需要标准定制的东西如下:
我在这里只找到了一个针对我的案例的实用指南,如下:如何更改 ListPreference 对话框的外观,但它有限且简短。我分析了 AndroidX API,看起来我需要更多时间来提出解决方案,因此任何帮助/想法都会受到赞赏......
谢谢,弗拉德。
只需重写 onClick() 函数即可弹出具有自定义布局的 AlertDialog。请记住在对话框中选择任何内容时调用 setValue()。
public class ColorPreference extends ListPreference {
private CharSequence[] mEntries;
private CharSequence[] mEntryValues;
private String mValue;
private String mSummary;
private AlertDialog mDialog;
public ColorPreference(Context context) {
this(context, null);
}
public ColorPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setDefaultValue(Options.DEFAULT_PRIMARY_COLOR_STRING);
}
@Override
protected void onClick() {
mEntries = getEntries();
mEntryValues = getEntryValues();
mSummary = getSummary().toString();
mValue = getValue();
mClickedDialogEntryIndex = findIndexOfValue(mValue);
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setSingleChoiceItems(new ColorAdapter(getContext(), R.layout.pref_color_item),mClickedDialogEntryIndex,null);
mDialog = builder.create();
mDialog.show();
}
}
package your.package.name;
import android.app.AlertDialog;
import android.content.Context;
import android.util.AttributeSet;
import androidx.preference.ListPreference;
public class CustomListPreference extends ListPreference {
public CustomListPreference (Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onClick() {
// If you are targeting Material Design 3 supersede AlertDialog.Builder with MaterialAlertDialogBuilder
AlertDialog.Builder builder = new AlertDialog.Builder(getContext()) // If you want to change the theme pass an R.style as the second argument
.setSingleChoiceItems(getEntries(), getValueIndex(), (dialog, index) -> {
if (callChangeListener(getEntryValues()[index].toString())) {
setValueIndex(index);
}
dialog.dismiss();
})
.setNegativeButton(getNegativeButtonText(), (dialog, which) -> dialog.dismiss())
//.setPositiveButton(getNegativeButtonText(), (dialog, which) -> dialog.dismiss())
//.setNeutralButton(getNegativeButtonText(), (dialog, which) -> dialog.dismiss())
.setTitle(getTitle());
AlertDialog dialog = builder.create();
dialog.show();
}
private int getValueIndex() {
CharSequence[] entryValues = getEntryValues();
String value = getValue();
for (int i = 0; i < entryValues.length; i++) {
if (entryValues[i].equals(value)) {
return i;
}
}
return -1;
}
}