自定义视图缩小:之前占用的空间没有被清除
Posted
技术标签:
【中文标题】自定义视图缩小:之前占用的空间没有被清除【英文标题】:Custom view shrinking: previously occupied space is not cleared 【发布时间】:2015-10-26 16:41:17 【问题描述】:在自定义视图中,OnMeasure和OnSizeChanged分别用于设置intrisic尺寸和获取最终尺寸。
在 OnDraw 中,使用当前的宽度/高度绘制可绘制对象。
现在,如果视图被告知要更改其内部大小,它将请求布局。这会触发 OnMeasure/OnSizeChanged,最后触发 OnDraw。 它工作正常,drawable 总是使用正确的内部尺寸显示。
问题是,如果新的内部尺寸比旧的小,android会离开旧的绘图(它似乎在新的“下方”,但实际上应该已经被android清除了)。
我试图清除 OnDraw 中的视图内容,但绘图矩形已被裁剪为新的视图大小。
这听起来像是 LinearLayout 中的一个错误,当孩子的视图尺寸缩小时不会清除其内容。在 Android 4.4 / Samsung S3 4G / CyanogenMod cm-11-20151004-NIGHTLY 上进行测试。
布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/content"
android:orientation="vertical"
android:layout_
android:layout_
android:background="#000000"
android:padding="8dp">
<LinearLayout
android:orientation="horizontal"
android:id="@+id/content"
android:layout_
android:layout_
android:layout_weight="1"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:gravity="top">
<LinearLayout
android:orientation="horizontal"
android:layout_
android:layout_
android:background="#CCD39F">
<MyCustomView
android:id="@+id/myview"
android:layout_
android:layout_ />
</LinearLayout>
</LinearLayout>
更新自定义视图大小后我看到的内容。应该只显示“黑色部分”,而不是白色部分。
应该是这样的:
【问题讨论】:
你能在不同的设备上试试吗?您也可以尝试将LinearLayout
替换为RelativeLayout
等其他布局。只是想隔离问题。还有Only the "black part" should be displayed, not the white one.
是什么意思
【参考方案1】:
我发现了问题和解决方法。 真正的问题在于LinearLayout。从 Android 4.0.3 到 Android 6。当这个垂直线性布局的 weight=1 和 height=0dp 时,它只有一个高度小于可用高度的孩子。这个孩子第一次画,没问题。如果这个孩子的高度缩小,它下面的区域不会重新绘制。所以它会保留第一个孩子的旧内容,而不是用布局背景颜色重新填充。
在下面的布局代码中,我演示了问题和解决方案。解决方案是添加第二个孩子,它将占用第一个孩子下方的剩余可用空间。使用这种技术,当第一个孩子缩小,第二个孩子扩大并且新的“空”空间被正确重绘时,它可以按预期工作。
所以这确实是 LinearLayout 的一个 bug。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_
android:layout_
android:background="#000000">
<LinearLayout
android:orientation="vertical"
android:layout_
android:layout_
android:layout_weight="1"
android:gravity="top">
<LinearLayout
android:orientation="horizontal"
android:layout_
android:layout_
android:background="#CCD39F">
<MyCustomView
android:id="@+id/icon"
android:layout_
android:layout_ />
</LinearLayout>
<!-- Solution. To see the problem, remove the following layout -->
<LinearLayout
android:orientation="vertical"
android:layout_
android:layout_
android:layout_weight="1"
android:background="#111111" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_
android:layout_
android:gravity="right">
<Button
android:text="Other demo"
android:layout_
android:layout_
android:id="@+id/btnNextImage" />
<Button
android:text="Next SVG"
android:layout_
android:layout_
android:id="@+id/btnGoEmpty" />
</LinearLayout>
</LinearLayout>
【讨论】:
以上是关于自定义视图缩小:之前占用的空间没有被清除的主要内容,如果未能解决你的问题,请参考以下文章
自定义导航栏 titleView 在加载新标题之前不会清除以前的标题