You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 00:33:20