应用场景:需要将多个按照顺序排列的View做出整体旋转的动画效果
是的,让容器旋转确实可以到达效果,但是由于性能....等需求,不用容器该怎么实现呢?
我们想旋转嘛,让每个View都在ValueAnimator里改变setRotationY不就行了。
final ValueAnimator animator = ValueAnimator.ofInt(0, 180);
animator.setDuration(2000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int animatedValue = (int) valueAnimator.getAnimatedValue();
for (View view : listViews) {
view.setRotationY(animatedValue);
}
}
});
几行代码迅速搞定
这里我们就谈谈这个rotationY的旋转原理了
View的rotationY方法以View的中心点的Y方向为旋转轴旋转。
camera则在该中心点的z轴正方向。
那么可以看见每个View都有自己的camera形成旋转投影效果,所以就会出现多View一起旋转混乱的情况。
有没有办法统一呢?有。那就是设定一个统一的camera位置,让所有View的camera都移动到该位置上,则就相当于一个camera投影不同的View。这个时候旋转View就可以达到整体的效果。
通过setPivotY和setPivotX可以调整camera所在位置。那么这个PivotY和PivotX参考的坐标系到底是在哪?PivotY和PivotX的参考坐标系是View的左上角。
现在思路很清晰了。就是设定一个camera的Y位置,然后通过setPivotY()让所有view的camera都移动到该位置。
具体做法:
- 以第一个view左上角为参考坐标系,得到camera的Y位置。
cameraY=所有view的height和/2 - Y值映射到各自的坐标系上。
PivotY=cameraY-上个view的height
if (isFirst) {
isFirst = false;
//计算总高度
float allHeight = 0;
for (View item : listViews) {
allHeight += item.getHeight();
}
//得到camera的Y值
float cameraY = allHeight / 2;
//将camera的Y值映射到每个View上,并移动到该位置
for (int i = 0; i < listViews.size(); i++) {
View itemView = listViews.get(i);
cameraY = cameraY - (i < 1 ? 0 : listViews.get(i - 1).getHeight());
itemView.setPivotY(cameraY);
}
}
animator.start();