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

修改Android无障碍字体大小后视图可见性未保留,求无需存值的解决方案

问题根本原因

修改系统无障碍字体大小触发了fontScale配置变更,Android系统默认会销毁并重建当前前台Activity,重新加载XML布局。你在运行时动态设置的GONE/INVISIBLE属于临时内存状态,默认不会被系统持久化,所以Activity重建后视图会回到XML中声明的默认可见状态。


无需额外定义变量存储可见性的可行方案

方案1:让Activity不响应字体大小变更的重建

直接在AndroidManifest.xml中对应Activity的声明里添加configChanges属性,指定由应用自己处理字体大小变更,不走系统销毁重建流程:

<activity
    android:name=".MainActivity"
    android:configChanges="fontScale|screenSize|smallestScreenSize"
    android:exported="true">
    <!-- 其他原有配置 -->
</activity>

添加后字体大小变更时Activity不会重建,所有视图的当前状态(包括可见性、输入内容等)都会自动保留。如果你需要在字体大小变更时做自定义适配,可以重写Activity的onConfigurationChanged方法处理对应逻辑,不需要的话可以不重写。

方案2:自定义视图实现状态自保存

原生View默认不会保存可见性状态,你可以自定义对应控件,重写状态保存和恢复的方法,让控件自己管理可见性状态,不需要Activity侧做额外处理:

class VisibilitySaveButton @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = android.R.attr.buttonStyle
) : AppCompatButton(context, attrs, defStyleAttr) {

    override fun onSaveInstanceState(): Parcelable {
        val bundle = Bundle()
        bundle.putParcelable("superState", super.onSaveInstanceState())
        bundle.putInt("visibility", visibility)
        return bundle
    }

    override fun onRestoreInstanceState(state: Parcelable?) {
        if (state is Bundle) {
            val superState = state.getParcelable<Parcelable>("superState")
            super.onRestoreInstanceState(superState)
            visibility = state.getInt("visibility")
            return
        }
        super.onRestoreInstanceState(state)
    }
}

之后把布局文件里的Button替换为你自定义的VisibilitySaveButton即可,系统配置变更导致Activity重建时,控件会自动恢复之前的可见性状态。


内容的提问来源于stack exchange,提问作者sadat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 03:36:02