Android如何创建仅展示信息的Preference组件
嘿,我之前做Android设置页的时候刚好碰到过一模一样的需求!你要的是那种有固定标题、能展示动态内容但用户完全不能编辑的Preference对吧?给你几个实用的方案,挑适合你的来:
方案1:最简单的快速实现(原生Preference+Summary)
如果可以接受动态内容显示在标题下方,这个方案最省事,直接用系统自带的Preference就行:
// 在你的Settings Activity/Fragment里 val myReadOnlyPref = findPreference<Preference>("pref_readonly_key") myReadOnlyPref?.run { title = "你的固定标题" // 设置好就不会变的标题 summary = "初始动态内容" // 这里放需要动态更新的文本 // 禁用点击事件,彻底阻止用户触发编辑行为 setOnPreferenceClickListener { true } } // 后续需要更新内容时,直接修改summary即可 myReadOnlyPref?.summary = "新的动态内容"
方案2:自定义布局实现「标题左+内容右」的样式
要是你想要和EditTextPreference一样的布局(标题在左,内容在右对齐),就自定义一个布局:
首先创建布局文件 res/layout/pref_readonly.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:paddingHorizontal="16dp" android:minHeight="?android:attr/listPreferredItemHeight"> <!-- 用系统自带的title id,保证和其他Preference风格统一 --> <TextView android:id="@android:id/title" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:textAppearance="?android:attr/textAppearanceListItem" android:textColor="?android:attr/textColorPrimary" android:maxLines="1" android:ellipsize="end"/> <!-- 用来显示动态内容的TextView --> <TextView android:id="@+id/pref_value" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceListItemSecondary" android:textColor="?android:attr/textColorSecondary" android:maxLines="1" android:ellipsize="end"/> </LinearLayout>
然后在你的偏好设置xml里引用这个Preference:
<Preference android:key="pref_readonly_key" android:title="你的固定标题" android:layout="@layout/pref_readonly"/>
最后在代码里绑定并更新内容:
val myReadOnlyPref = findPreference<Preference>("pref_readonly_key") myReadOnlyPref?.apply { setOnPreferenceClickListener { true } // 禁用点击 // 初始设置内容 updatePrefValue(this, "初始动态内容") } // 写个工具方法方便后续重复调用更新 private fun updatePrefValue(pref: Preference, value: String) { val valueView = pref.view?.findViewById<TextView>(R.id.pref_value) valueView?.text = value } // 之后要更新内容时直接调用 updatePrefValue(myReadOnlyPref!!, "更新后的动态内容")
方案3:完全自定义Preference类(优雅的长期方案)
如果你的项目里需要多个这类只读Preference,自定义一个专属类会更方便维护:
创建 ReadOnlyPreference.kt:
class ReadOnlyPreference(context: Context, attrs: AttributeSet) : Preference(context, attrs) { private var currentValue: String = "" // 给外部提供更新内容的方法 fun setDisplayValue(value: String) { if (currentValue != value) { currentValue = value notifyChanged() // 通知UI刷新 } } override fun onBindViewHolder(holder: PreferenceViewHolder) { super.onBindViewHolder(holder) // 绑定动态内容到布局 val valueView = holder.findViewById(R.id.pref_value) as TextView valueView.text = currentValue // 彻底禁用交互 holder.itemView.isClickable = false holder.itemView.isFocusable = false } override fun onCreateView(parent: ViewGroup): View { return LayoutInflater.from(context).inflate(R.layout.pref_readonly, parent, false) } }
然后在偏好设置xml里使用:
<com.your.app.package.ReadOnlyPreference android:key="pref_readonly_key" android:title="你的固定标题"/>
代码里调用:
val myReadOnlyPref = findPreference<ReadOnlyPreference>("pref_readonly_key") myReadOnlyPref?.setDisplayValue("初始动态内容") // 后续更新内容 myReadOnlyPref?.setDisplayValue("最新的动态内容")
这几个方案都能完美满足你的需求:固定标题、动态更新内容、用户完全无法编辑。
内容的提问来源于stack exchange,提问作者J K
相关产品推荐
相关产品推荐

