You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android表格应用旋转时Switch控件状态显示异常排查

解决旋转屏幕时Switch控件状态显示不一致的问题

你遇到的核心问题是系统自动恢复Switch的旧选中状态,覆盖了你代码中设置的正确值——虽然日志显示你已经把isChecked设置成了对应的数据值,但屏幕旋转触发Activity重建时,系统的View状态恢复机制会在你的代码执行之后再运行,导致UI显示和实际数据脱节。

问题根源

Switch继承自CompoundButton,这类控件默认会基于自身id自动保存选中状态。当屏幕旋转时,Activity重建流程中,系统会在你设置isChecked之后,调用onRestoreInstanceState把控件恢复到旋转前的状态,这就直接覆盖了你设置的正确值,最终造成UI显示和日志打印的状态不符。

快速解决方案

你可以通过两种方式解决这个问题:

方案1:在布局中禁用自动状态保存

直接给Switch添加android:saveEnabled="false"属性,让系统不再保存这个控件的状态:

<Switch android:id="@+id/tv_outputItemBoolean"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:trackTint="@color/switch_track_selector"
    android:thumbTint="@color/switch_thumb_selector"
    android:clickable="true"
    android:paddingLeft="15dp"
    android:paddingRight="15dp"
    android:paddingBottom="2.5dp"
    android:paddingTop="2.5dp"
    android:textSize="20sp"
    android:gravity="center"
    android:saveEnabled="false" /> <!-- 新增该行 -->

方案2:在代码中先禁用状态保存再设置值

如果不想修改布局,可以在代码里先关闭Switch的自动状态保存,再设置选中状态:

val switch: Switch = view.findViewById(R.id.tv_outputItemBoolean)
switch.saveEnabled = false // 先禁用自动状态保存
val value = col.data as Boolean
switch.isChecked = value
switch.hint = c.getText(DataType.stringResourceOf(value))

额外性能优化建议

你的getView方法没有复用传入的rowView参数,每次都创建新的TableRow,这会在屏幕旋转或表格滚动时造成不必要的性能浪费。建议改成复用已有的视图:

fun getView(position: Int, rowView: TableRow?, parent: TableLayout): TableRow {
    val currentRowView = rowView ?: TableRow(parent!!.context)
    currentRowView.removeAllViews() // 清空旧的子视图
    val rowData = this.getItem(position)
    for (i in 0..columnCounts - 1) {
        val data: ColumnData<*>? = rowData[i]
        currentRowView.addView(this.getColumnView(data, null, currentRowView))
    }
    return currentRowView
}

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

火山引擎 最新活动