2014-03-27 201 views
2

我想通过layout.addView(view)方法动态添加一个新视图到布局。新的视图不应该是可见的,但我希望它的显示列表被创建,因此当我决定显示它时(通过动画,例如淡入),它不必重绘(调用onDraw方法)本身。当通过addView方法动态添加视图时,onDraw会调用两次

我运行此代码:

customView = new CustomView(this.getContext()); 
customView .setAlpha(0.0f); 
this.addView(customView); // 'this' is RelativeLayout instance in this case 

的onDraw方法被调用为customView,一切都很好。但是,当我更改布局中的任何内容(按下按钮,滚动,导致布局无效的任何内容)时,我的customView的onDraw方法将被第二次调用。之后,如果我不使自定义视图失效(正确的行为),则不会再调用它。

我不知道为什么Android的行为如此。我希望它创建customView,调用onDraw,为它创建一个显示列表,并且不会再调用onDraw,直到我使视图无效。总之,onDraw应该被调用一次。

而且它与customView的初始隐形无关,如果alpha设置为0.5f,行为是相同的。

我的问题是,如何使Android调用onDraw一次?

如果Android真的需要两次调用onDraw,那么我应该怎么做才能在this.addView(view)之后的代码中执行它?没有设置任何计时器,因为这将是完全丑陋的。

回答

2

您所描述的行为是好的,是Android框架对视图对象的部分 -

**Drawing** 

Drawing is handled by walking the tree and rendering each view that intersects 
the invalid region. Because the tree is traversed in-order, this means that 
parents will draw before (i.e., behind) their children, with siblings drawn 
in the order they appear in the tree. If you set a background drawable 
for a View, then the View will draw it for you before calling back to its 
onDraw() method. 
Note that the framework will not draw views that are not in the invalid region. 
To force a view to draw, call invalidate() 
(Taken from the official google android API docs). 

这意味着您的自定义视图是由包含该按钮\滚动条同样的观点包含
等等,如果你不用它来渲染evrytime,你的视图所在的
子树就会调用onDraw方法,你可以将视图的布尔标志设置为false - use setWillNotDraw()来做到这一点。
(你应该把它放在活动的onCreate上,以便使视图设置这个标志为false(这也是默认设置),并且当你想渲染视图时使用invalidate()。
您可以阅读official google docs了解更多信息。

+0

对不起,但我认为你的解决方案没有意义(显然这是行不通的)。你明白我的问题吗?带有this.addView的代码被调用一次,只有onDraw被调用两次。 – r00dY

+0

然后我完全误解了你的问题..你可以试着让它更清楚吗? – crazyPixel

+0

告诉我哪一部分你不明白,我会尽力解释它更好:) – r00dY

相关问题