java - 首选项屏幕中的自定义列表首选项对话框布局,带有自定义列表项

标签 java android dialog customdialog listpreference

我想在单击“设置 Activity ”中的“列表首选项”时创建自定义列表对话框。

root_preferences.xml 中的 ListPreference:

  <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" />

我希望它具有圆角,并且我还想要自定义列表项 View (例如,使用图像而不是默认的单选按钮)。

实际结果:

enter image description here

预期结果:

enter image description here

我可以使用 ListPreference 来执行此操作,但用适配器替换 @array 条目吗?

是否有其他方法可以实现此目的而不需要摆脱 PreferenceScreen?

最佳答案

同时,我已经找到了解决方案。它可能不是最干净的,但它对我有用。如果有人知道更好的解决方案,请随时告诉我们。

  1. 创建一个扩展 DialogPreference 的类。创建与您想要的自定义对话框一样多的类,例如LanguagePreferenceUnitPreference

    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;
       }
    }
    
  2. 现在您可以在 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>
    
  3. 创建一个扩展 DialogFragment 的(可以是抽象的)。删除 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);
        }
    }
    
  4. RoundedPreferenceDialog扩展类,例如LanguagePreferenceDialogUnitPreferenceDialog

    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;
       }
    }
    
  5. 重写 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);
         }
     }
    
  6. 现在您可以显示自定义对话框而不是默认对话框。您只需按照您想要的方式自定义即可。要使其圆角,请将根布局的背景设置为自定义圆角布局。

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。)
  • 最终结果:

    enter image description here

    关于java - 首选项屏幕中的自定义列表首选项对话框布局,带有自定义列表项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60748852/

    相关文章:

    Symfony PHP 中的 JavaScript 确认(..) 等效项

    java - 在 fragment 的对话框内显示 GridView

    java - 如何使用 SpringTemplateLoader 而不是 FiletemPlateLoader 配置 Freemarker

    java - 断言集合包含自定义类的对象,它不会覆盖 equals/hashcode

    java - 从左上角绘制点击之间的绘制线

    java - Android 访问不同类的 Canvas

    android - Android/iPad 上的加密存储

    android - 在 Linux 桌面上运行 Android NDK 二进制文件

    javascript - 带有 HTML5 Dialog .showModal() 方法的 reCAPTCHA v2

    java - Android - MediaPlayer 崩溃