这几天在看属性动画,突然想到可以实现自己手机的桌面启动的加载动画,就实现一下,效果如下图所示:
我的实现思路很简单,先实现单个方块的动画效果,再实现整体的联动效果。
(1)单个方块的动画效果:
为了易于扩展,我使用了自定义View来实现小红方块,并且创建了四个方法用来体现不同方向的移动动画。通过属性动画ObjectAnimator来实现动画效果。因为是组合动画,所以使用AnimatorSet,以向右移动为例:
public void rotateRight() {
toX = formX + 200f;
ObjectAnimator scaleX = ObjectAnimator.ofFloat(this, "scaleX", 1, 0.5f, 1);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(this, "scaleY", 1, 0.5f, 1);
ObjectAnimator animator1 = ObjectAnimator.ofFloat(this, "rotation", 0, -90f);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(this, "translationX", formX, toX);
ObjectAnimator animator3 = ObjectAnimator.ofFloat(this, "translationY", formY, toY);
formX = toX;
AnimatorSet set = new AnimatorSet();
set.playTogether(animator1, animator2, animator3, scaleX, scaleY);
set.setDuration(300);
set.start();
}
这里面几个参数说明一下:
—scaleX:表示动画执行过程中X(宽度)的变化。1,0.5f,1 代表初始宽度为100%,向着50%变化,最后回到100%,ScaleY同理,即缩放动画
—translationX:表示动画执行工程中控件X坐标的变化,fromX代表初始位置X坐标,toX代表结束位置即位移动画
—rotation:表示动画执行过程中控件角度的变化,0代表开始的角度,1代表结束的角度,即旋转动画
—playTogether:表示动画时同时进行的。
我们看下效果:
小控件的部分就ok了,现在通过ViewGroup将其八个小方块联动起来。
(2)方块联动效果
首先,自定义ViewGroup,添加8个方块,按顺序排列好。为了之后的联动效果,我将使用下列顺序进行排序:
代码:
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
for (int i = 0; i < 8; i++) {
View childView = getChildAt(i);
int h, s;
if (i == 0) {
h = 1;
s = 2;
childView.layout(50 + h * 200, 50 + s * 200, h * 200 + 200, s * 200 + 200);
} else if (i == 1) {
h = 0;
s = 2;
childView.layout(50 + h * 200, 50 + s * 200, h * 200 + 200, s * 200 + 200);
} else if (i == 2) {
h = 0;
s = 1;
childView.layout(50 + h * 200, 50 + s * 200, h * 200 + 200, s * 200 + 200);
} else if (i == 3) {
h = 0;
s = 0;
childView.layout(50 + h * 200, 50 + s * 200, h * 200 + 200, s * 200 + 200);
} else if (i == 4) {
h = 1;
s = 0;
childView.layout(50 + h * 200, 50 + s * 200, h * 200 + 200, s * 200 + 200);
} else if (i == 5) {
h = 2;
s = 0;
childView.layout(50 + h * 200, 50 + s * 200, h * 200 + 200, s * 200 + 200);
} else if (i == 6) {
h = 2;
s = 1;
childView.layout(50 + h * 200, 50 + s * 200, h * 200 + 200, s * 200 + 200);
} else if (i == 7) {
h = 1;
s = 1;
childView.layout(50 + h * 200, 50 + s * 200, h * 200 + 200, s * 200 + 200);
}
}
然后就是找控件的动画规律了,我们发现,控件8不动,控件1-7循环执行动画,且执行的动画也是在(右,右,下,下,左,左,上,上,右,右,下,下。。。)循环播放的。
有了规律,代码就好写了:
//用于记录方块翻滚方向的规律
List<Integer> integerList;
public void initIntegerList() {
integerList = new ArrayList<>();
integerList.add(0);
integerList.add(0);
integerList.add(1);
integerList.add(1);
integerList.add(2);
integerList.add(2);
integerList.add(3);
integerList.add(3);
}
void move(int index) {
if(index%integerList.size() == 0 ||index%integerList.size() == 1) {
((BlockView)getChildAt(index%7)).rotateRight();
} else if (index%integerList.size() == 2 ||index%integerList.size() == 3) {
((BlockView)getChildAt(index%7)).rotateDown();
} else if (index%integerList.size() == 4 ||index%integerList.size() == 5) {
((BlockView)getChildAt(index%7)).rotateLeft();
} else if (index%integerList.size() == 6 ||index%integerList.size() == 7) {
((BlockView)getChildAt(index%7)).rotateUp();
}
}
现在,方块就可以联动的转起来了。目前方块的大小,颜色,动画的效果,执行的时间都是常量。可以根据需要去设置成变量,可以更加灵活一些。