状态类错误,应为视图状态,但收到的是类android.widget.CompoundButton$SavedState

w8f9ii69  于 2022-11-03  发布在  Android
关注(0)|答案(9)|浏览(147)

java.lang.IllegalArgumentException: Wrong state class,应为视图状态,但收到的却是class android.widget.CompoundButton$SavedState。当两个不同类型的视图在同一层次结构中具有相同的ID时,通常会发生这种情况。此视图的ID为ID/0x 2。请确保其他视图未使用相同的ID。
它发生时,屏幕旋转,当试图回到片段没有id是重复plzz有人帮助我

ars1skjm

ars1skjm1#

正如问题所描述的为什么会发生这种情况。
当两个不同类型的视图在同一层次结构中具有相同的id时,通常会发生这种情况。
确切地说,会有两种不同类型的视图具有相同的id,这可能发生在动态膨胀视图上。在我的例子中,我有两个ViewStub,具有相同的视图idinflatedId,因此,在视图膨胀后。应用程序进入一种状态,即一个ViewStub和另一个膨胀的视图存在于具有相同id的视图层次结构中,这导致崩溃。

olqngx59

olqngx592#

在我的例子中,我实现了onRestoreInstanceState,但没有正确地尝试将我的自定义SavedState类发送到super.onRestoreInstanceState
我通过发送savedState.getSuperState到超级呼叫解决了它。

wyyhbhjk

wyyhbhjk3#

我已经解决了它....这是因为重复的id的视图主要是当我们添加视图动态和不设置id(与相同的文本单选按钮在我的情况下)
要解决此问题,请首先检查您正在动态添加的所有视图

5ssjco0h

5ssjco0h4#

我在处理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)
}

我所要做的就是把viewState返回到superClass而不是state。我想这是因为“视图的状态”还没有恢复。我们传递了state参数,在那一刻,根据我们收到的错误,它只是一个原始包。我们还没有提取和分配实际的view state(这发生在if块中),我们将其隐藏在第一个函数中,这就是为什么错误说“错误的状态类”,这也是为什么使用viewState工作。我希望这有帮助!

qnzebej0

qnzebej05#

假设您在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的名称。

wgxvkvu9

wgxvkvu96#

类似的事情发生在我身上,在我的情况下,我有一个布局为纵向模式和一个为横向模式。两者有其相似之处,但有两个按钮,有相同的ID在两个布局,但这两个按钮的类型是不同的横向布局。所以当我改变设备的方向,以横向类似的错误发生。修复是有相同类型的按钮在两个布局。

qlckcl4x

qlckcl4x7#

我收到了错误,除了我没有重复的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())
}
a0zr77ik

a0zr77ik8#

我使用的是带有选项卡布局的查看分页器,问题是:

return TabLayoutMediator(binding.tabLayout, binding.viewpager, true) { tab, position ->
    tab.text = "hello $position"
    tab.id = position
}

将id替换为其他内容,如tag

mwg9r5ms

mwg9r5ms9#

在我的例子中,我没有重复的ID。当我尝试从深色主题切换到浅色主题时,错误发生了。这两个主题都有不同的父主题。请确保浅色主题和深色主题使用相同的主题样式和父主题。

相关问题