错误状态 class,需要查看状态但收到 class android.widget.CompoundButton$SavedState
Wrong state class, expecting View State but received class android.widget.CompoundButton$SavedState instead
java.lang.IllegalArgumentException: Wrong state class
,需要查看状态,但收到的却是 class android.widget.CompoundButton$SavedState
。当不同类型的两个视图在同一层次结构中具有相同的 id 时,通常会发生这种情况。此视图的 id 是 id/0x2。确保其他视图不使用相同的 ID。
它发生在屏幕旋转时,当尝试返回片段时没有重复 id 请有人帮助我
我已经解决了....这是因为视图的 ID 重复,主要是当我们动态添加视图而不设置 ID 时(在我的情况下具有相同的单选按钮文本)
要解决,首先检查您动态添加的所有视图
假设您在 Fragment 或 DialogFragment 中有一个 ScrollView,id 为:
android:id="@+id/scrollView"
您显示此片段,然后更改屏幕方向,并发生此崩溃:
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo { com.company.MyApp/com.company.MyActivity }:
java.lang.IllegalArgumentException: Wrong state class, expecting View State
but received class android.widget.ScrollView$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/scrollView. Make sure other
views do not use the same id.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
...
Caused by: java.lang.IllegalArgumentException: Wrong state class...
at android.view.View.onRestoreInstanceState(View.java:13764)
at android.support.v4.widget.NestedScrollView.onRestoreInstanceState(NestedScrollView.java:1879)
...
解决方法是重命名您正在使用的 ID,如下所示:
android:id="@+id/scroll_view"
我假设某些 id 名称已被 Android 框架中的其他视图使用,因此在恢复视图状态时 将它们检测为重复名称。所以你必须改变你的id的名字。
正如问题所描述的那样。
This usually happens when two views of different type have the same id
in the same hierarchy.
确切地说,会有两种不同类型的视图具有相同的 id,这可能发生在动态膨胀视图上。
在我的例子中,我有两个 ViewStub
具有相同的视图 id
和 inflatedId
,因此,在一个视图的 inflation 之后。应用程序进入一种状态,即一个 ViewStub 和其他膨胀的视图存在于视图层次结构中,具有相同的 id,这导致了崩溃。
在我的例子中,我实施的 onRestoreInstanceState
没有正确地尝试将我的自定义 SavedState
class 发送到 super.onRestoreInstanceState
我解决了发送 savedState.getSuperState
到 super 调用的问题。
类似的事情发生在我身上,在我的例子中,我有一种布局用于纵向模式,另一种用于横向模式。两者有相似之处,但有两个按钮在两种布局上具有相同的 Id,但是这两个按钮的类型在横向布局中不同。因此,当我将设备的方向更改为横向时,会发生类似的错误。修复是在两种布局中使用相同类型的按钮。
除了我没有重复的 ID 之外,我还收到了错误消息。
我的代码是这样的:
override fun onSaveInstanceState(): Parcelable {
val bundle = Bundle()
bundle.putString(SELECTED_KEY, selectedItemId)
bundle.putParcelable(SUPER_STATE_KEY, super.onSaveInstanceState())
return bundle
}
override fun onRestoreInstanceState(state: Parcelable) {
if (state is Bundle) {
selectedItemId = state.getString(SELECTED_KEY, null)
selectedItemId?.let{
views.forEach {view ->
view.isSelected = it == view.tag
}
}
}
super.onRestoreInstanceState(state)
}
我看到有一个未解决的问题 here。当我像这样更改 super.onRestoreInstanceState
调用参数时,我设法找到了一个不会使应用程序崩溃的解决方法:
override fun onSaveInstanceState(): Parcelable {
val bundle = Bundle()
vgs_ring?.constraintLayoutParams()?.let {
bundle.putParcelable(PARENT_STATE_KEY, super.onSaveInstanceState())
bundle.putFloat(RING_POSITION_KEY, it.verticalBias)
}
super.onSaveInstanceState()
return bundle
}
override fun onRestoreInstanceState(state: Parcelable) {
var parentState : Parcelable? = null
if (state is Bundle) {
val curRingPosition = state.getFloat(RING_POSITION_KEY, DEFAULT_RING_POSITION)
state.getParcelable<Parcelable?>(PARENT_STATE_KEY)?.let {
parentState = it
}
vgs_ring?.constraintLayoutParams()?.let {
it.verticalBias = curRingPosition
calculateRingPosition()
}
}
super.onRestoreInstanceState(parentState ?: super.onSaveInstanceState())
}
我只是在使用 customViews 和 parcelable 时处理这个问题,试图用 onSaveInstanceState()
和 onRestoreInstanceState()
保持我的视图状态,但我遇到了同样的错误。但是,当我更改上述这些功能的实现时,我找到了解决方法。我会分享之前和之后。
这是我以前的。差别很小。
override fun onSaveInstanceState(): Parcelable {
val bundle = Bundle()
bundle.putParcelable("superState", super.onSaveInstanceState())
bundle.putParcelableArrayList("boxState", ArrayList(boxen))
super.onSaveInstanceState()
return bundle
}
override fun onRestoreInstanceState(state: Parcelable) {
var viewState = state
if (viewState is Bundle) {
boxen = viewState.getParcelableArrayList("boxState")!!
viewState = viewState.getParcelable("superState")!!
}
val test = boxen
Log.i(TAG, "Bundle received: $boxen and $test and finally $viewState")
super.onRestoreInstanceState(state)
}
这是我的追求。
override fun onSaveInstanceState(): Parcelable {
val bundle = Bundle()
bundle.putParcelable("superState", super.onSaveInstanceState())
bundle.putParcelableArrayList("boxState", ArrayList(boxen))
super.onSaveInstanceState()
return bundle
}
override fun onRestoreInstanceState(state: Parcelable) {
var viewState = state
if (viewState is Bundle) {
boxen = viewState.getParcelableArrayList("boxState")!!
viewState = viewState.getParcelable("superState")!!
}
val test = boxen
Log.i(TAG, "Bundle received: $boxen and $test and finally $viewState")
super.onRestoreInstanceState(viewState)
}
我所要做的只是 return viewState
到超类而不是 state
。我认为这是因为可以这么说,“观点的状态”还没有恢复。我们正在传递 state
参数,而在那一刻,根据我们收到的错误,它只是一个原始包。我们还没有提取并分配我们隐藏在第一个函数中的实际 view state
(发生在 if 块中),这就是错误显示“错误状态 class”的原因,这也是为什么使用viewState
成功了。希望对您有所帮助!
java.lang.IllegalArgumentException: Wrong state class
,需要查看状态,但收到的却是 class android.widget.CompoundButton$SavedState
。当不同类型的两个视图在同一层次结构中具有相同的 id 时,通常会发生这种情况。此视图的 id 是 id/0x2。确保其他视图不使用相同的 ID。
它发生在屏幕旋转时,当尝试返回片段时没有重复 id 请有人帮助我
我已经解决了....这是因为视图的 ID 重复,主要是当我们动态添加视图而不设置 ID 时(在我的情况下具有相同的单选按钮文本)
要解决,首先检查您动态添加的所有视图
假设您在 Fragment 或 DialogFragment 中有一个 ScrollView,id 为:
android:id="@+id/scrollView"
您显示此片段,然后更改屏幕方向,并发生此崩溃:
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo { com.company.MyApp/com.company.MyActivity }:
java.lang.IllegalArgumentException: Wrong state class, expecting View State
but received class android.widget.ScrollView$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/scrollView. Make sure other
views do not use the same id.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
...
Caused by: java.lang.IllegalArgumentException: Wrong state class...
at android.view.View.onRestoreInstanceState(View.java:13764)
at android.support.v4.widget.NestedScrollView.onRestoreInstanceState(NestedScrollView.java:1879)
...
解决方法是重命名您正在使用的 ID,如下所示:
android:id="@+id/scroll_view"
我假设某些 id 名称已被 Android 框架中的其他视图使用,因此在恢复视图状态时 将它们检测为重复名称。所以你必须改变你的id的名字。
正如问题所描述的那样。
This usually happens when two views of different type have the same id in the same hierarchy.
确切地说,会有两种不同类型的视图具有相同的 id,这可能发生在动态膨胀视图上。
在我的例子中,我有两个 ViewStub
具有相同的视图 id
和 inflatedId
,因此,在一个视图的 inflation 之后。应用程序进入一种状态,即一个 ViewStub 和其他膨胀的视图存在于视图层次结构中,具有相同的 id,这导致了崩溃。
在我的例子中,我实施的 onRestoreInstanceState
没有正确地尝试将我的自定义 SavedState
class 发送到 super.onRestoreInstanceState
我解决了发送 savedState.getSuperState
到 super 调用的问题。
类似的事情发生在我身上,在我的例子中,我有一种布局用于纵向模式,另一种用于横向模式。两者有相似之处,但有两个按钮在两种布局上具有相同的 Id,但是这两个按钮的类型在横向布局中不同。因此,当我将设备的方向更改为横向时,会发生类似的错误。修复是在两种布局中使用相同类型的按钮。
除了我没有重复的 ID 之外,我还收到了错误消息。 我的代码是这样的:
override fun onSaveInstanceState(): Parcelable {
val bundle = Bundle()
bundle.putString(SELECTED_KEY, selectedItemId)
bundle.putParcelable(SUPER_STATE_KEY, super.onSaveInstanceState())
return bundle
}
override fun onRestoreInstanceState(state: Parcelable) {
if (state is Bundle) {
selectedItemId = state.getString(SELECTED_KEY, null)
selectedItemId?.let{
views.forEach {view ->
view.isSelected = it == view.tag
}
}
}
super.onRestoreInstanceState(state)
}
我看到有一个未解决的问题 here。当我像这样更改 super.onRestoreInstanceState
调用参数时,我设法找到了一个不会使应用程序崩溃的解决方法:
override fun onSaveInstanceState(): Parcelable {
val bundle = Bundle()
vgs_ring?.constraintLayoutParams()?.let {
bundle.putParcelable(PARENT_STATE_KEY, super.onSaveInstanceState())
bundle.putFloat(RING_POSITION_KEY, it.verticalBias)
}
super.onSaveInstanceState()
return bundle
}
override fun onRestoreInstanceState(state: Parcelable) {
var parentState : Parcelable? = null
if (state is Bundle) {
val curRingPosition = state.getFloat(RING_POSITION_KEY, DEFAULT_RING_POSITION)
state.getParcelable<Parcelable?>(PARENT_STATE_KEY)?.let {
parentState = it
}
vgs_ring?.constraintLayoutParams()?.let {
it.verticalBias = curRingPosition
calculateRingPosition()
}
}
super.onRestoreInstanceState(parentState ?: super.onSaveInstanceState())
}
我只是在使用 customViews 和 parcelable 时处理这个问题,试图用 onSaveInstanceState()
和 onRestoreInstanceState()
保持我的视图状态,但我遇到了同样的错误。但是,当我更改上述这些功能的实现时,我找到了解决方法。我会分享之前和之后。
这是我以前的。差别很小。
override fun onSaveInstanceState(): Parcelable {
val bundle = Bundle()
bundle.putParcelable("superState", super.onSaveInstanceState())
bundle.putParcelableArrayList("boxState", ArrayList(boxen))
super.onSaveInstanceState()
return bundle
}
override fun onRestoreInstanceState(state: Parcelable) {
var viewState = state
if (viewState is Bundle) {
boxen = viewState.getParcelableArrayList("boxState")!!
viewState = viewState.getParcelable("superState")!!
}
val test = boxen
Log.i(TAG, "Bundle received: $boxen and $test and finally $viewState")
super.onRestoreInstanceState(state)
}
这是我的追求。
override fun onSaveInstanceState(): Parcelable {
val bundle = Bundle()
bundle.putParcelable("superState", super.onSaveInstanceState())
bundle.putParcelableArrayList("boxState", ArrayList(boxen))
super.onSaveInstanceState()
return bundle
}
override fun onRestoreInstanceState(state: Parcelable) {
var viewState = state
if (viewState is Bundle) {
boxen = viewState.getParcelableArrayList("boxState")!!
viewState = viewState.getParcelable("superState")!!
}
val test = boxen
Log.i(TAG, "Bundle received: $boxen and $test and finally $viewState")
super.onRestoreInstanceState(viewState)
}
我所要做的只是 return viewState
到超类而不是 state
。我认为这是因为可以这么说,“观点的状态”还没有恢复。我们正在传递 state
参数,而在那一刻,根据我们收到的错误,它只是一个原始包。我们还没有提取并分配我们隐藏在第一个函数中的实际 view state
(发生在 if 块中),这就是错误显示“错误状态 class”的原因,这也是为什么使用viewState
成功了。希望对您有所帮助!