LayoutParams type changed at runtime. ClassCastException: ViewGroup$LayoutParams cannot be cast to ViewGroup$MarginLayoutParams

huangapple 未分类评论45阅读模式
英文:

LayoutParams type changed at runtime. ClassCastException: ViewGroup$LayoutParams cannot be cast to ViewGroup$MarginLayoutParams

问题

以下是翻译的内容:

我尝试以编程方式设置布局参数。在我的片段中,在 `onCreate` 方法中,我设置了 `ScrollView` 的 LayoutParams,它起作用。但是,我还有一个观察者,在这个观察者中,当满足某些条件时,我再次更改了这个 `ScrollView` 的布局参数。但问题是,在 `onCreate` 中的相同代码在观察者中不起作用。下面是在 `onCreate` 方法中设置布局参数并设置观察者的片段。更改布局参数的方法是复制粘贴的,所以它为什么在一个时间点能正常工作,而一毫秒后却不能呢?

**onCreate:**
```kotlin
Log.d("在 onCreate 方法中设置高度")
binding.scrollRoot.layoutParams = ViewGroup.LayoutParams(
    ViewGroup.LayoutParams.MATCH_PARENT,
    binding.txtCars.lineHeight * SIZE + 10
)


cars.observe(viewLifecycleOwner, Observer {
    if (it.size < SIZE)
    {
        Log.d("在观察者方法中设置高度")
        binding.scrollRoot.layoutParams = ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            binding.txtCars.lineHeight * (it.size) + 10
        )
    }
    binding.txtCars.text = formatCars(it, requireContext())
})

Logcat:

D/AppDebug: 在 onCreate 方法中设置高度
D/AppDebug: 在观察者方法中设置高度
I/zygote64: 方法超出编译器指令限制:void org.ccil.cowan.tagsoup.HTMLSchema.<init>()
D/AndroidRuntime: 关闭 ViewModel
E/AndroidRuntime: 致命异常: 主线程
    进程: com.example.fuelmanager, PID: 8034
    java.lang.ClassCastException: 无法将 android.view.ViewGroup$LayoutParams 转换为 android.view.ViewGroup$MarginLayoutParams
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6662)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
        at android.view.View.measure(View.java:22216)
        ...
        (错误栈继续)

经过研究,我找到了这个问题
>在这里,您正在用更通用的 ViewGroup.LayoutParams 替换正确类型 AbsListView.LayoutParams 的现有布局参数。布局参数类型是视图的父容器的类型。
>如果您需要修改现有的布局参数,请使用 getLayoutParams() 访问它们,进行修改,并调用 requestLayout() 来通知布局已更改。

所以我按照以下方式实现:

Log.d("在观察者方法中设置高度")
val layoutParams = binding.scrollRoot.layoutParams
layoutParams.height = binding.txtCars.lineHeight * (it.size) + 10

而且它起作用。

但我的问题是,在 onCreate() 之后,ViewGroup/ScrollView 的 LayoutParams 类型是如何改变的。 在观察者中发生了什么,导致出现这个错误?


<details>
<summary>英文:</summary>

I try to set layout params programmatically. In my fragment in `onCreate` method, I set LayoutParams of the `ScrollView` and it works. But also, I have an observer and in this observer when some condition is true I change layout params of this `ScrollView` again. But the problem is that the same code which is in `onCreate` doesn&#39;t work in an observer. Below is a fragment of `onCreate` method when I set layout params and set an observer. The method which changes layout params is copy-pasted so it is a little strange why it is working and a milliseconds after doesn&#39;t.

**onCreate:**

Log.d("Setting height in onCreate method")
binding.scrollRoot.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
binding.txtCars.lineHeight * SIZE + 10
)

cars.observe(viewLifecycleOwner, Observer {
if (it.size < SIZE)
{
Log.d("Setting height in observer method")
binding.scrollRoot.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
binding.txtCars.lineHeight * (it.size) + 10
)
}
binding.txtCars.text = formatCars(it, requireContext())
})


**Logcat:**

D/AppDebug: Setting height in onCreate method
D/AppDebug: Setting height in observer method
I/zygote64: Method exceeds compiler instruction limit: 25337 in void org.ccil.cowan.tagsoup.HTMLSchema.<init>()
D/AndroidRuntime: Shutting down ViewModel
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.fuelmanager, PID: 8034
java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.view.ViewGroup$MarginLayoutParams
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6662)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:22216)
at androidx.constraintlayout.widget.ConstraintLayout.internalMeasureChildren(ConstraintLayout.java:1227)
at androidx.constraintlayout.widget.ConstraintLayout.onMeasure(ConstraintLayout.java:1572)
at android.view.View.measure(View.java:22216)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6671)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:22216)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6671)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:22216)
at androidx.drawerlayout.widget.DrawerLayout.onMeasure(DrawerLayout.java:1156)
at android.view.View.measure(View.java:22216)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6671)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143)
at android.view.View.measure(View.java:22216)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6671)
at androidx.appcompat.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:403)
at android.view.View.measure(View.java:22216)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6671)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:22216)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6671)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1539)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:823)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:702)
at android.view.View.measure(View.java:22216)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6671)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:831)
at android.view.View.measure(View.java:22216)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2596)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1638)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1892)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1522)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7292)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:981)
at android.view.Choreographer.doCallbacks(Choreographer.java:790)
at android.view.Choreographer.doFrame(Choreographer.java:721)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:967)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:101)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7529)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)


After research, I found [this question](https://stackoverflow.com/questions/21045198/android-view-viewgrouplayoutparams-cannot-be-cast-to-android-widget-abslistview/21045396)
&gt;Here you&#39;re replacing existing layout params of correct type `AbsListView.LayoutParams` with more generic `ViewGroup.LayoutParams`. Layout params type is that of the parent container of the view.  
&gt;If you need to modify existing layout params, access them with `getLayoutParams()`, modify it, and call `requestLayout()` to notify that the layout has changed.

So I made it in that way:

Log.d("Setting height in observer method")
val layoutParams = binding.scrollRoot.layoutParams
layoutParams.height = binding.txtCars.lineHeight * (it.size) + 10

And it works.

**But my question is how is it possible that type of `ViewGroup`/`ScrollView` LayoutParams changed.** What happened after `onCrete()` that makes this error in the observer?




</details>


huangapple
  • 本文由 发表于 2020年7月24日 07:14:53
  • 转载请务必保留本文链接:https://java.coder-hub.com/63064464.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定