我已阅读过有关Property Animation和Hardware Acceleration的信息,但我仍然不确定使用动画类的最有效方法是什么。 (为了这个问题,我不需要在Honeycomb之前支持设备。所以我想使用动画师类。)
例如,假设我有一个视图。在这个视图中,我有一个我想要淡入的BitmapDrawable。视图中还有许多其他元素不会改变。
动画师最好使用哪些属性或对象?可画的?我在onDraw中绘制位图的颜料?还有别的吗?
如何通过硬件加速实现最高效?这是否需要为动画的每个步骤调用invalidate,或者是否有一种方法可以仅为drawable设置动画,而不是为动画的每一步完全重绘视图的其余部分?
我想我认为最佳情况是视图的其余部分不必在软件中完全重绘,而是硬件加速有效地淡化了drawable。
对推荐方法的任何建议或指示?
谢谢!
答案 0 :(得分:4)
使用Object Property Animators,基本上它们只是重复调用" setN()"方法每X毫秒,其中" N"是您想要更改的属性。
在alpha的情况下提供的示例中,两者都需要调用invalidate()
来重绘您正在制作动画的视图。不同之处在于,当您在setAlpha()
对象上调用View
时,它会为您调用invalidate()
。如果您要将目标对象设置为用于绘制drawable的Paint
对象,则仍需要在invalidate()
上调用View
,以便使用新的Paint
重绘{1}}参数。
理想情况下,您希望将目标设置为最高级别的子级,以便重绘仅在要设置动画的视图上进行。例如,如果将目标设置为根视图,它将在整个ViewGroup中的每个子节点上调用invalidate()
,这将反过来调用ViewGroup中每个子节点上的draw()
。如果您将其设置为顶级ImageView
,则只会重新绘制ImageView
。
为了最好地利用硬件,您需要使用图层属性。首先,您需要确定要制作动画的最顶级父视图。如果您只想淡化Drawable
,那么它将是Drawable
或包含View
。如果你想淡化一切,那么它将是根视图。无论您决定制作动画,都会立即应用于View
。
在启动Animator之前,在父视图上使用setLayerType()
。将其设置为View#LAYER_TYPE_HARDWARE
。然后设置AnimationListener
并在完成动画制作工具后将LayerType重置为View#LAYER_TYPE_SOFTWARE
或View#LAYER_TYPE_NONE
。
myParentView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
myObjectAnimator.addListener(new ViewAnimator.AnimatorListener() {
public void onAnimationEnd(Animator animation) {
myParentView.setLayerType(View.LAYER_TYPE_NONE);
}
public void onAnimationRepeat(Animator animation) {
}
public void onAnimationStart(Animator animation) {
}
public void onAnimationCancel(Animator animation) {
myParentView.setLayerType(View.LAYER_TYPE_NONE, null);
}
}
myObjectAnimator.start();
在这种情况下,如果您要使用myParentView
属性翻译translateX
,那么它会将图层myParentView
及其所有孩子放入一个平面。把它放入硬件内存。全部翻译整个视图。然后,完成后,从内存中删除myParentView
。
修改强>
最后一点,Alpha对CPU造成了严重破坏。如果你有半个alpha的东西并在视图中翻译它,那么渲染将比你简单地翻译视图更难。谨慎使用它。
答案 1 :(得分:1)
也许,您可以在原始视图上叠加一个新视图(仅包含动画师)。新视图设置为透明。
如果没有原始视图,您应该执行的重置无效新视图。
答案 2 :(得分:1)
在完成您的查询后,我建议您仔细阅读standard document,这样可以让您了解如何正确使用invalidate()
。其次,android API已经提供了不同的方法来处理不同情况下的动画。
Here,我希望你的大部分疑虑都会被清除。请仔细阅读各个小节和相关博客提及的内容。
希望这会对你有所帮助。