点击自定义Preference后如何强制刷新重绘隐藏New标签TextView
问题描述
- 当前现状:用户进入设置页面时,存在一个前缀带有“New”标识的选项,点击该选项目前无任何响应。
- 实现目标:用户进入设置页面并点击带有“New”前缀的选项时,“New”前缀的可见性需设置为
View.GONE。
为简化代码片段,假设所有布局及其引用均已正确配置、可正常访问
现有实现代码
MyCustomPreference.kt
class MyCustomPreference @JvmOverloads constructor( context: Context, val attr: AttributeSet? = null, private val defStyleAttr: Int = 0 ) : Preference(context, attr, defStyleAttr) { init { layoutResource = R.layout.my_layout } var showNewLabel = false override fun onBindViewHolder(holder: PreferenceViewHolder) { super.onBindViewHolder(holder) with(holder.itemView.findViewById<TextView>(R.id.text_view_new)) { visibility = if (showNewLabel) { View.VISIBLE } else { View.GONE } } } }
setupPreferences.kt
// 假设所有逻辑均正常运行(例如onViewCreated、onCreate生命周期回调) open class PreferenceFragment : PreferenceFragmentCompat() { override fun onResume() { super.onResume() setupPreference() } private fun setupPreference() { findPreference<MyCustomPreference>(getText(R.string.my_custom_pref_key))?.apply { showNewLabel = true // 可正确显示(若设为false则隐藏)TextView setOnPreferenceClickListener { // 问题点:此处操作无法更新UI隐藏TextView // 自定义MyCustomPreference的onBindViewHolder不会被再次调用 // 若尝试手动获取TextView引用,其返回值为null showNewLabel = false // 此处返回true或false不影响最终结果 true } } } }
现存问题
当setupPreference中设置的点击监听器被触发时,UI没有发生任何变化。MyCustomPreference仅会在用户退出并重新进入设置菜单时才会重新渲染。需要确认:在已知CustomPreference的属性(showNewLabel)已发生变更的情况下,是否有方法可以强制渲染该CustomPreference?
解决方案
修改showNewLabel属性后,调用Preference原生提供的notifyChanged()方法,即可强制当前Preference重新绑定ViewHolder,触发onBindViewHolder执行,即时完成UI刷新。
修改代码
优化MyCustomPreference的showNewLabel属性实现,在属性赋值时自动调用刷新逻辑,无需每次修改属性后手动触发刷新:
class MyCustomPreference @JvmOverloads constructor( context: Context, val attr: AttributeSet? = null, private val defStyleAttr: Int = 0 ) : Preference(context, attr, defStyleAttr) { init { layoutResource = R.layout.my_layout } var showNewLabel = false set(value) { field = value notifyChanged() // 属性变更时通知Preference刷新对应条目UI } override fun onBindViewHolder(holder: PreferenceViewHolder) { super.onBindViewHolder(holder) with(holder.itemView.findViewById<TextView>(R.id.text_view_new)) { visibility = if (showNewLabel) View.VISIBLE else View.GONE } } }
原有点击监听器中的逻辑无需额外修改,赋值showNewLabel = false时会自动触发UI刷新,点击后“New”标识会立即隐藏。
原理说明:
notifyChanged()是AndroidX Preference库的标准API,作用是通知绑定的PreferenceAdapter当前Preference的数据发生变更,需要重新执行onBindViewHolder渲染对应列表条目,不会出现手动获取View返回null的问题。
内容的提问来源于stack exchange,提问作者EsotericLanguage
相关产品推荐
相关产品推荐

