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

Android XML仅一个ID却报重复ID错误?配置变更崩溃求助

Android配置变更时View状态恢复崩溃问题(三星Android 13设备)

错误日志

java.lang.IllegalArgumentException: Wrong state class, expecting ViewState but received class com.google.android.material.button.MaterialButton$SavedState instead. This usually happens when two views of different type have the same id in the same hierarchy. This view's id is id/left_arrow_btn. Make sure other views do not use the same id

相关代码

XML布局代码

<Button
         android:id="@+id/left_arrow_btn"
         android:layout_width="24dp"
         android:layout_height="24dp"
         android:layout_gravity="left"
         android:layout_marginLeft="10dp"
         android:layout_marginRight="10dp"
         android:background="@drawable/arrow_left"
         android:gravity="left"
         android:visibility="gone" />

Kotlin调用代码

var left_arrow:Button = findViewById(R.id.left_arrow_btn)
left_arrow.setOnClickListener {
                       rWebView?.goBack()
 }

补充信息

  • 已确认项目中仅存在一个left_arrow_btn ID
  • 错误在配置变更(如屏幕旋转)导致onCreate被调用两次时触发
  • 仅在Android 13的三星设备上崩溃,Android 12/13模拟器及部分Android 12实体设备运行正常

解决方案

方案1:统一View类型为MaterialButton

将XML中的<Button>替换为<com.google.android.material.button.MaterialButton>,同时更新Kotlin代码中的类型声明:

<com.google.android.material.button.MaterialButton
         android:id="@+id/left_arrow_btn"
         android:layout_width="24dp"
         android:layout_height="24dp"
         android:layout_gravity="left"
         android:layout_marginLeft="10dp"
         android:layout_marginRight="10dp"
         android:background="@drawable/arrow_left"
         android:gravity="left"
         android:visibility="gone" />
var left_arrow: MaterialButton = findViewById(R.id.left_arrow_btn)
left_arrow.setOnClickListener {
    rWebView?.goBack()
}

方案2:阻止系统自动替换View类型

在XML的Button标签中添加android:viewClass="android.widget.Button",强制系统使用原生Button类,避免被替换为MaterialButton:

<Button
         android:id="@+id/left_arrow_btn"
         android:viewClass="android.widget.Button"
         android:layout_width="24dp"
         android:layout_height="24dp"
         android:layout_gravity="left"
         android:layout_marginLeft="10dp"
         android:layout_marginRight="10dp"
         android:background="@drawable/arrow_left"
         android:gravity="left"
         android:visibility="gone" />

方案3:跳过单个View的状态恢复(不推荐)

如果不需要保存该按钮的状态,可以在onCreate中移除对应View的状态数据后再调用super.onCreate:

override fun onCreate(savedInstanceState: Bundle?) {
    savedInstanceState?.let { bundle ->
        val viewState = bundle.getParcelable<Parcelable>("android:viewHierarchyState") as? SparseArray<Parcelable>
        viewState?.remove(R.id.left_arrow_btn)
    }
    super.onCreate(savedInstanceState)
    // 后续初始化代码
}

问题原因

三星Android 13设备在使用MaterialComponents主题时,会自动将布局中的原生Button替换为MaterialButton,但在配置变更恢复状态时,系统仍按照原Button类型去读取SavedState,导致类型不匹配引发崩溃。其他设备/模拟器无此自动替换逻辑,因此未出现问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 10:52:52