如何为final类PreferenceScreen实现自定义布局(Java)
解决PreferenceScreen(final类)自定义视图并保留原有功能的方案
方案一:通过PreferenceFragmentCompat统一处理视图绑定
步骤1:创建自定义布局文件
创建res/layout/custom_preference_screen_layout.xml,结构参考你的自定义ListPreference布局,包含所需控件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/llBackground" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="16dp"> <ImageView android:id="@+id/ivPreferenceIcon" android:layout_width="24dp" android:layout_height="24dp" android:layout_gravity="center_vertical" android:marginEnd="16dp"/> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical"> <TextView android:id="@+id/tvTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="16sp"/> <TextView android:id="@+id/tvSummary" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="14sp"/> </LinearLayout> </LinearLayout>
步骤2:在Preference XML中指定布局
直接给PreferenceScreen设置android:layout属性:
<androidx.preference.PreferenceScreen android:enabled="false" android:key="bg_keys" android:persistent="false" android:summary="@string/cv19" app:icon="@drawable/d5" android:layout="@layout/custom_preference_screen_layout" android:title="@string/cv20"> <CustomListPreference android:entries="@array/backgroundnames" android:entryValues="@array/backgroundvalues" android:key="baund_" android:summary="@string/summary" android:title="@string/title" /> <CustomListPreference android:entries="@array/btnames" android:entryValues="@array/btvalues" android:key="btvalue" android:title="@string/titlefome" /> </androidx.preference.PreferenceScreen>
步骤3:在PreferenceFragmentCompat中绑定视图
重写onBindPreferenceViewHolder方法,针对PreferenceScreen类型的项处理自定义视图逻辑:
public class YourPreferenceFragment extends PreferenceFragmentCompat { @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(R.xml.your_preference_xml, rootKey); } @Override public void onBindPreferenceViewHolder(@NonNull Preference preference, @NonNull PreferenceViewHolder holder) { super.onBindPreferenceViewHolder(preference, holder); if (preference instanceof PreferenceScreen) { PreferenceScreen screen = (PreferenceScreen) preference; // 获取自定义布局控件 ImageView customIcon = holder.itemView.findViewById(R.id.ivPreferenceIcon); TextView customTitle = holder.itemView.findViewById(R.id.tvTitle); TextView customSummary = holder.itemView.findViewById(R.id.tvSummary); LinearLayout llBackground = holder.itemView.findViewById(R.id.llBackground); // 设置内容 customIcon.setImageDrawable(screen.getIcon()); customTitle.setText(screen.getTitle()); customSummary.setText(screen.getSummary()); // 根据启用状态设置样式 if (screen.isEnabled()) { llBackground.setBackground(requireContext().getResources().getDrawable(R.drawable.playlist_rect_box_shape)); customTitle.setTextColor(Color.parseColor("#ffffff")); customSummary.setTextColor(Color.parseColor("#807d7d")); } else { llBackground.setBackground(requireContext().getResources().getDrawable(R.drawable.playlist_rect_box_disabled)); customTitle.setTextColor(Color.parseColor("#999999")); customSummary.setTextColor(Color.parseColor("#6A6868")); } } } }
方案二:给单个PreferenceScreen设置绑定监听器
如果仅需给特定PreferenceScreen设置自定义视图,可直接在onCreatePreferences中给目标控件绑定监听器:
@Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(R.xml.your_preference_xml, rootKey); // 找到目标PreferenceScreen PreferenceScreen bgScreen = findPreference("bg_keys"); if (bgScreen != null) { // 设置自定义布局 bgScreen.setLayoutResource(R.layout.custom_preference_screen_layout); // 设置视图绑定监听器 bgScreen.setOnBindViewHolderListener(holder -> { ImageView customIcon = holder.itemView.findViewById(R.id.ivPreferenceIcon); TextView customTitle = holder.itemView.findViewById(R.id.tvTitle); TextView customSummary = holder.itemView.findViewById(R.id.tvSummary); LinearLayout llBackground = holder.itemView.findViewById(R.id.llBackground); customIcon.setImageDrawable(bgScreen.getIcon()); customTitle.setText(bgScreen.getTitle()); customSummary.setText(bgScreen.getSummary()); if (bgScreen.isEnabled()) { llBackground.setBackground(requireContext().getResources().getDrawable(R.drawable.playlist_rect_box_shape)); customTitle.setTextColor(Color.parseColor("#ffffff")); customSummary.setTextColor(Color.parseColor("#807d7d")); } else { llBackground.setBackground(requireContext().getResources().getDrawable(R.drawable.playlist_rect_box_disabled)); customTitle.setTextColor(Color.parseColor("#999999")); customSummary.setTextColor(Color.parseColor("#6A6868")); } }); } }
核心原理
PreferenceScreen虽为final类,但继承自Preference,因此拥有setLayoutResource和setOnBindViewHolderListener等方法,可像普通Preference一样替换布局并自定义视图绑定逻辑,同时保留其跳转子设置页面的核心功能。
内容的提问来源于stack exchange,提问作者Ravinder Singh
相关产品推荐
相关产品推荐

