当父视图的任何子视图重绘时,如何触发父视图的重绘?
背景
我已经编写了一个基于 LinearLayout
的自定义 Android 视图,我将其称为 ReflectingLayout
。这个想法相当简单,在 ReflectingLayout
中声明的任何子视图下方渲染反射效果。例如..
我通过重写 dispatchDraw() 来实现这一点
在ReflectingLayout
如下:
@Override
protected void dispatchDraw(Canvas canvas) {
Bitmap bitmap = Bitmap.createBitmap(...);
Canvas tempCanvas = new Canvas(bitmap);
// Draw child views to bitmap using tempCanvas
super.dispatchDraw(tempCanvas);
...
// some tranformations performed on bitmap
...
// draw transformed image on to main canvas
canvas.drawBitmap(bitmap, 0, 0, null);
}
问题
如果我的 ReflectingLayout
包含一个 TextView
并且我更改了该 TextView
的文本内容code> 反射效果未更新。
我相信这是因为 Android 只会重绘 TextView
本身,而不是重绘所有父视图,这意味着我重写的 dispatchDraw()
方法不会被调用。
是否有任何简单的方法可以触发父视图的重绘以响应其任何子视图的更改?
特别是,如何使我的 ReflectingLayout
在以下情况下重绘:子视图被重绘?
我已经考虑过的事情
我注意到一个新的
View.OnLayoutChangeListener
已在 API 级别 11 中添加。大概这可用于注册父视图的回调并触发重绘(?)。无论如何,我需要一个可以在 API 7 级以上运行的解决方案。我可以简单地扩展
TextView
和我想在ReflectingLayout
中声明的任何其他 View 类,以在重绘时使它们的父级无效,但这是一个笨拙的解决方案。
收到的任何帮助(包括您认为整体方法是错误的)。
谢谢。
Background
I have written a custom Android View based on a LinearLayout
which I have called ReflectingLayout
. The idea is fairly simple, to render a reflection effect below any child Views declared within the ReflectingLayout
. e.g...
I am achieving this by overriding dispatchDraw()
in ReflectingLayout
as follows:
@Override
protected void dispatchDraw(Canvas canvas) {
Bitmap bitmap = Bitmap.createBitmap(...);
Canvas tempCanvas = new Canvas(bitmap);
// Draw child views to bitmap using tempCanvas
super.dispatchDraw(tempCanvas);
...
// some tranformations performed on bitmap
...
// draw transformed image on to main canvas
canvas.drawBitmap(bitmap, 0, 0, null);
}
The Problem
If my ReflectingLayout
contains, say, a TextView
and I change the text content of that TextView
the reflection effect is not updating.
I believe this is because Android will only redraw the TextView
itself rather than all the parent views as well, meaning my overridden dispatchDraw()
method does not get called.
Is there any simple way to trigger the redrawing of a parent view in response to changes in any of it's child views?
In particular, how can I make my ReflectingLayout
be redrawn when child views are redrawn?
Things I've already considered
I've noticed that a new
View.OnLayoutChangeListener
was added in API Level 11. Presumably this could be used to register a callback to the parent view and trigger a redraw(?). In any case, I need a solution which will work on API Level 7 upwards.I could simply extend
TextView
and any other View class I want to declare insideReflectingLayout
to invalidate their parent as they are redrawn, but this is a clunky solution.
Any help greatly received (including if you think the overall approach is wrong).
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在您的视图中使用
getParent()
方法怎么样?像这样的事情:What about using
getParent()
method in your view? Something like this:我刚刚遇到这个问题。我发现这是由于 3.0+ 中新的硬件加速支持所致。我解决这个问题的方法是使用
View#setLayerType
和使用LAYER_TYPE_SOFTWARE
。为了继续以 API 级别 8 为目标,我使用反射在支持的 Android 平台上调用此方法。这解决了问题,现在当子项无效时,我的自定义 ViewGroup 可以正确绘制。我不知道这是否能准确解决您的问题,但它可能会帮助其他也对此问题感到困惑的人。
反射代码,非常基本:
I just encountered this problem. I figured out it was due to the new hardware acceleration support in 3.0+ The way I solved it was using
View#setLayerType
and usingLAYER_TYPE_SOFTWARE
. In order to continue targeting API level 8 I used reflection to call this method on supporting android platforms. This solved the issue and now my custom ViewGroup draws properly when the children are invalidated.I don't know if this will solve your problem exactly but it may help others who are also perplexed by this issue.
Reflection code, pretty basic: