我有一个包含多个自定义视图的复杂框架布局。主视图是图表。
覆盖图形是一个自定义视图,它表示一个十字线指针,用户可以在图形上拖动以读取有关特定数据点的详细信息。
框架布局捕获所有触摸事件,在每个子视图上调用“命中测试”方法,以确定触摸是否在该视图上,然后将触摸事件调度到适当的视图。
当用户触摸十字线并拖动它时,我将触摸事件传递给它用来更新它的位置并使其自身无效的十字线。
一切正常,除了......
当我使任何这些子视图无效时,布局中的所有视图都会重绘。我知道这一点,因为我在开发者选项中打开了“show screen updates”。在任何时候我都不会使包含的FrameLayout无效 - 或者至少,不是故意的。
当然,处理布局的Activity不会使它失效,我在子视图中没有任何对父级的引用。
我没有发布代码,因为a)我不知道这可能是正常行为,b)有很多! c)如果这不是正常行为,我不知道代码的哪一部分存在问题。当然,我很乐意提供任何可能要求的东西。
我的最低API是2.3.3,我的目标是4.0。这两个版本都会发生这种情况,所以我怀疑我的代码是问题,但从哪里开始?
有关可能发生的事情的任何线索?
答案 0 :(得分:6)
View
无法绘制“只是自己”,因为它取决于它的父级(通过Canvas
方法提供它的剪切和翻译dispatchDraw
)。失效要求整个视图树无效 - 这是您正在寻找的答案:)
如果您要查看ViewGroup
的来源,您会发现有两个重要方法:dispatchDraw
(负责将绘制事件分配给它的孩子)和drawChild
(由dispatchDraw
调用,让你指定如何绘制子项)。请注意,虽然有View
指定了无效区域,但没有检查哪个RectF
开始失效。据我所知 - 您需要确保无效View
(交叉)不占用整个屏幕,因此重绘将只是实际需要的部分。
答案 1 :(得分:2)
如果理解正确,十字线视图的线条覆盖整个屏幕,即从上到下的一条垂直线和从左到右的一条水平线。
现在,如果您更改十字准线的中心并且其他视图不会被重绘,那么您的屏幕很快就会被前一个十字线位置的旧线条混乱。你不会想要这个,所以你可以很高兴其他观点也重新绘制。
如果需要,可以指定“脏”矩形并调用invalidate(Rect dirty),这不会重绘完全在该矩形之外的视图。虽然在这种情况下取决于你,但不要改变那个矩形之外的任何东西。
答案 2 :(得分:0)
试试这个:
setDrawingCacheEnabled(true);
如果视图未更改
,则启用视图的绘图缓存将使视图不被重绘答案 3 :(得分:0)
答案可能很简单,但是我在帮助下解决了这个问题:
this.invalidate()
为每个画布视图运行它,它将一一更新(并非一次更新)