修改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
相关产品推荐
相关产品推荐

