求适配AndroidX PreferenceScreen的Java自定义Preference示例
AndroidX Preference 自定义实现示例(ColorPicker/NumberPicker)
以下是适配AndroidX Preference Library的Java自定义Preference示例,包含ColorPickerPreference和NumberPickerPreference,直接基于AndroidX组件扩展,无需依赖第三方库。
1. ColorPickerPreference 实现
点击后弹出颜色选择对话框,选中颜色自动保存到SharedPreferences,同时在Preference项上展示颜色预览与色值。
import android.content.Context; import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.util.AttributeSet; import android.view.View; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.preference.DialogPreference; import androidx.preference.PreferenceViewHolder; public class ColorPickerPreference extends DialogPreference { private int mCurrentColor; private static final int DEFAULT_COLOR = Color.WHITE; public ColorPickerPreference(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); setDialogLayoutResource(R.layout.dialog_color_picker); setPositiveButtonText(android.R.string.ok); setNegativeButtonText(android.R.string.cancel); } @Override protected void onBindViewHolder(@NonNull PreferenceViewHolder holder) { super.onBindViewHolder(holder); // 更新预览区域的颜色和色值文本 ImageView colorPreview = (ImageView) holder.findViewById(R.id.color_preview); TextView colorValue = (TextView) holder.findViewById(R.id.color_value); if (colorPreview != null) { colorPreview.setBackground(new ColorDrawable(mCurrentColor)); } if (colorValue != null) { colorValue.setText(String.format("#%06X", (0xFFFFFF & mCurrentColor))); } } @Override protected void onSetInitialValue(@Nullable Object defaultValue) { mCurrentColor = getPersistedInt(defaultValue != null ? (Integer) defaultValue : DEFAULT_COLOR); } @Override protected Object onGetDefaultValue(@NonNull TypedArray a, int index) { return a.getColor(index, DEFAULT_COLOR); } @Override protected void showDialog(@Nullable Bundle state) { super.showDialog(state); AlertDialog dialog = (AlertDialog) getDialog(); if (dialog != null) { android.widget.ColorPickerView colorPicker = dialog.findViewById(R.id.color_picker); if (colorPicker != null) { colorPicker.setColor(mCurrentColor); colorPicker.setOnColorChangedListener(color -> mCurrentColor = color); } dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(v -> { if (callChangeListener(mCurrentColor)) { persistInt(mCurrentColor); notifyChanged(); dialog.dismiss(); } }); } } }
对应对话框布局res/layout/dialog_color_picker.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <android.widget.ColorPickerView android:id="@+id/color_picker" android:layout_width="match_parent" android:layout_height="200dp" /> </LinearLayout>
2. NumberPickerPreference 实现
点击后弹出带滚轮选择器的对话框,支持自定义数值范围,选中数值自动保存并更新Preference摘要。
import android.content.Context; import android.content.res.TypedArray; import android.os.Bundle; import android.util.AttributeSet; import android.view.View; import android.widget.NumberPicker; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.preference.DialogPreference; public class NumberPickerPreference extends DialogPreference { private int mCurrentValue; private int mMinValue = 0; private int mMaxValue = 100; private static final int DEFAULT_VALUE = 50; public NumberPickerPreference(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); setDialogLayoutResource(R.layout.dialog_number_picker); setPositiveButtonText(android.R.string.ok); setNegativeButtonText(android.R.string.cancel); // 读取xml中配置的数值范围属性 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NumberPickerPreference); mMinValue = a.getInt(R.styleable.NumberPickerPreference_minValue, mMinValue); mMaxValue = a.getInt(R.styleable.NumberPickerPreference_maxValue, mMaxValue); a.recycle(); } @Override protected void onSetInitialValue(@Nullable Object defaultValue) { mCurrentValue = getPersistedInt(defaultValue != null ? (Integer) defaultValue : DEFAULT_VALUE); setSummary(String.valueOf(mCurrentValue)); } @Override protected Object onGetDefaultValue(@NonNull TypedArray a, int index) { return a.getInt(index, DEFAULT_VALUE); } @Override protected void showDialog(@Nullable Bundle state) { super.showDialog(state); AlertDialog dialog = (AlertDialog) getDialog(); if (dialog != null) { NumberPicker numberPicker = dialog.findViewById(R.id.number_picker); if (numberPicker != null) { numberPicker.setMinValue(mMinValue); numberPicker.setMaxValue(mMaxValue); numberPicker.setValue(mCurrentValue); // 禁用手动输入,仅保留滚轮选择 numberPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS); } dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(v -> { if (numberPicker != null) { int newValue = numberPicker.getValue(); if (callChangeListener(newValue)) { mCurrentValue = newValue; persistInt(mCurrentValue); setSummary(String.valueOf(mCurrentValue)); dialog.dismiss(); } } }); } } }
对应对话框布局res/layout/dialog_number_picker.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:padding="16dp"> <NumberPicker android:id="@+id/number_picker" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
添加自定义属性到res/values/attrs.xml:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="NumberPickerPreference"> <attr name="minValue" format="integer" /> <attr name="maxValue" format="integer" /> </declare-styleable> </resources>
在PreferenceScreen中使用
在你的偏好设置xml中直接引用自定义Preference:
<?xml version="1.0" encoding="utf-8"?> <androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <com.yourpackage.ColorPickerPreference android:key="theme_color" android:title="主题颜色" android:defaultValue="#FFFFFF"/> <com.yourpackage.NumberPickerPreference android:key="count_value" android:title="数量设置" android:defaultValue="50" app:minValue="0" app:maxValue="200"/> </androidx.preference.PreferenceScreen>
依赖配置
确保模块级build.gradle中包含AndroidX Preference依赖:
dependencies { implementation 'androidx.preference:preference:1.2.0' }
内容的提问来源于stack exchange,提问作者tm1701
相关产品推荐
相关产品推荐

