首选项屏幕中的自定义列表首选项对话框布局,带有自定义列表项
Custom list preference dialog layout in Preference Screen, with custom list items
我想在单击“设置”中的 ListPreference 时创建自定义列表对话框 Activity。
ListPreference root_preferences.xml:
<ListPreference
android:icon="@drawable/pref_language"
app:defaultValue="en"
app:entries="@array/language_entries"
app:entryValues="@array/language_values"
app:iconSpaceReserved="false"
app:key="@string/prefkey_language"
app:summary="%s"
app:title="@string/language_title" />
我希望它具有圆角,并且我还希望自定义列表项视图(例如图像而不是默认的单选按钮)。
实际结果:
预期结果:
我可以使用 ListPreference 的方式执行此操作,但用适配器替换 @array 条目吗?
有没有其他方法可以在不需要摆脱 PreferenceScreen 的情况下实现这一点?
同时,我找到了解决办法。它可能不是最干净的,但它对我有用。如果有人知道更好的解决方案,请不要犹豫告诉我们。
创建一个扩展 DialogPreference 的 class。创建尽可能多的 classes 你想要的自定义对话框,例如LanguagePreference、UnitPreference 等
public class LanguagePreference extends DialogPreference implements Preference.OnPreferenceChangeListener {
public LanguagePreference(Context context, AttributeSet attrs) {
super(context, attrs);
setOnPreferenceChangeListener(this);
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// do something
return true;
}
}
现在您可以在root_preferences.xml中使用它们。
<PreferenceCategory app:title="@string/category">
<com.company.yourapp.preferences.LanguagePreference
android:icon="@drawable/pref_language"
app:title="@string/language" />
<com.company.yourapp.preferences.UnitPreference
android:icon="@drawable/pref_unit"
app:title="@string/unit" />
</PreferenceCategory>
创建一个扩展 DialogFragment 的 class(可能是抽象的)。删除 onViewCreated() 中的默认背景和标题。
public abstract class RoundedPreferenceDialog extends DialogFragment {
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
if (getDialog() != null && getDialog().getWindow() != null) {
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); // remove default background so that dialog can be rounded
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); // remove default title
}
super.onViewCreated(view, savedInstanceState);
}
}
从 RoundedPreferenceDialog 扩展 classes,例如LanguagePreferenceDialog、UnitPreferenceDialog.
public class LanguagePreferenceDialog extends RoundedPreferenceDialog {
public static LanguagePreferenceDialog newInstance() {
return new LanguagePreferenceDialog();
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialogpreference_language, container, false);
// init UI, list adapter, listeners
return view;
}
}
重写 SettingsFragment 中的 onDisplayPreferenceDialog。为您拥有的每个自定义对话框创建一个条件。
@Override
public void onDisplayPreferenceDialog(Preference preference) {
if (preference instanceof LanguagePreference) { // rounded language dialog
LanguagePreferenceDialog.newInstance().show(getParentFragmentManager(), null);
} else if (preference instanceof UnitPreference) { // rounded unit dialog
UnitPreferenceDialog.newInstance().show(getParentFragmentManager(), null);
} else {
super.onDisplayPreferenceDialog(preference);
}
}
现在您可以显示自定义对话框而不是默认对话框。您只需按照您想要的方式对其进行自定义。要使其成为圆形,请将根布局的背景设置为自定义圆形布局。
dialogpreference_language.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dialogLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_dialog_rounded">
<!-- titleTextView, languageListView, cancelButton, etc. -->
</RelativeLayout>
bg_dialog_rounded.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/dialog_radius" />
<solid android:color="@color/white" />
</shape>
- 在列表项布局文件中设置列表项的样式,例如listitem_language.xml,在适配器中充气。 (下例中的ImageView+TextView。)
最终结果:
我想在单击“设置”中的 ListPreference 时创建自定义列表对话框 Activity。
ListPreference root_preferences.xml:
<ListPreference
android:icon="@drawable/pref_language"
app:defaultValue="en"
app:entries="@array/language_entries"
app:entryValues="@array/language_values"
app:iconSpaceReserved="false"
app:key="@string/prefkey_language"
app:summary="%s"
app:title="@string/language_title" />
我希望它具有圆角,并且我还希望自定义列表项视图(例如图像而不是默认的单选按钮)。
实际结果:
预期结果:
我可以使用 ListPreference 的方式执行此操作,但用适配器替换 @array 条目吗?
有没有其他方法可以在不需要摆脱 PreferenceScreen 的情况下实现这一点?
同时,我找到了解决办法。它可能不是最干净的,但它对我有用。如果有人知道更好的解决方案,请不要犹豫告诉我们。
创建一个扩展 DialogPreference 的 class。创建尽可能多的 classes 你想要的自定义对话框,例如LanguagePreference、UnitPreference 等
public class LanguagePreference extends DialogPreference implements Preference.OnPreferenceChangeListener { public LanguagePreference(Context context, AttributeSet attrs) { super(context, attrs); setOnPreferenceChangeListener(this); } @Override public boolean onPreferenceChange(Preference preference, Object newValue) { // do something return true; } }
现在您可以在root_preferences.xml中使用它们。
<PreferenceCategory app:title="@string/category"> <com.company.yourapp.preferences.LanguagePreference android:icon="@drawable/pref_language" app:title="@string/language" /> <com.company.yourapp.preferences.UnitPreference android:icon="@drawable/pref_unit" app:title="@string/unit" /> </PreferenceCategory>
创建一个扩展 DialogFragment 的 class(可能是抽象的)。删除 onViewCreated() 中的默认背景和标题。
public abstract class RoundedPreferenceDialog extends DialogFragment { @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { if (getDialog() != null && getDialog().getWindow() != null) { getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); // remove default background so that dialog can be rounded getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); // remove default title } super.onViewCreated(view, savedInstanceState); } }
从 RoundedPreferenceDialog 扩展 classes,例如LanguagePreferenceDialog、UnitPreferenceDialog.
public class LanguagePreferenceDialog extends RoundedPreferenceDialog { public static LanguagePreferenceDialog newInstance() { return new LanguagePreferenceDialog(); } @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.dialogpreference_language, container, false); // init UI, list adapter, listeners return view; } }
重写 SettingsFragment 中的 onDisplayPreferenceDialog。为您拥有的每个自定义对话框创建一个条件。
@Override public void onDisplayPreferenceDialog(Preference preference) { if (preference instanceof LanguagePreference) { // rounded language dialog LanguagePreferenceDialog.newInstance().show(getParentFragmentManager(), null); } else if (preference instanceof UnitPreference) { // rounded unit dialog UnitPreferenceDialog.newInstance().show(getParentFragmentManager(), null); } else { super.onDisplayPreferenceDialog(preference); } }
现在您可以显示自定义对话框而不是默认对话框。您只需按照您想要的方式对其进行自定义。要使其成为圆形,请将根布局的背景设置为自定义圆形布局。
dialogpreference_language.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dialogLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_dialog_rounded">
<!-- titleTextView, languageListView, cancelButton, etc. -->
</RelativeLayout>
bg_dialog_rounded.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/dialog_radius" />
<solid android:color="@color/white" />
</shape>
- 在列表项布局文件中设置列表项的样式,例如listitem_language.xml,在适配器中充气。 (下例中的ImageView+TextView。)
最终结果: