0
点赞
收藏
分享

微信扫一扫

Android Study 之 属性动画初识


LZ-Says:看透不说透,凡事儿不过尔尔~


一、回顾

今天,一起来说说Android动画的那些事儿。

首先来回顾下,面试可能会问到的问题:

谈谈Android中的动画,包含几种,分别都是什么

这个问题回答,应该从俩个方面去回答:

  • Android 3.0 之前,提供补间动画(BetweenAnimation)和逐帧动画(FrameAnimation);
  • Android 3.0 之后,推出属性动画。

Q1:那么他们之前区别?

A1:如果按照使用范围,应该分为俩种:

  • 操作View:补间动画和属性动画;
  • 操作图片:逐帧动画

A2:如果按照性质,应该分为俩种:

  • 视图动画;
  • 属性动画

Q3:那么他们具体又是做什么的?

逐帧动画:将一系列的图片依次进行播放,从而达到给用户显示动态的效果,类似Gif动态图。简单举个例子:


Android Study 之 属性动画初识_android_02

如上图,我们要实现的是上图的小人进行走动,如何实现?


Android Study 之 属性动画初识_插值器_03

我们实际上需要UI提供一个个小人的不同动作,通过逐帧动画进行“拼接”,之后便给用户显示既是小人动的效果~

补间动画:通过设置View状态类型,例如:平移(Translate)、旋转(Rotate)、缩放(Scale)、透明(Alpha);

**属性动画:**Android 3.0 后推出,通过设置View属性,也可以进行组合从而达到效果。

这里不得不提有关补间动画的一个小bug。

补间动画小bug

我们使用补间动画实现一个View平移的效果,代码很Easy:

首先编写translate文件:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:fillAfter="true"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="50%p"
android:toYDelta="0" />

在View点击事件中进行引用:

// 补间动画
public void getTranslate(View view) {
Animation animation = AnimationUtils.loadAnimation(this, R.anim.translate);
view.startAnimation(animation);
}

我们先来看一下效果:


Android Study 之 属性动画初识_属性动画_04

乍眼一看,似乎没有问题,但是,当我们点击移动后的位置确是无效的,而点击原来的位置,则会再次触发,如下图:


Android Study 之 属性动画初识_属性动画_05

LZ这里简单说明下原因:补间动画,只是简单的绘制了效果后的View,真正的View还是在原处,不信你瞧着:


Android Study 之 属性动画初识_android_06

原点依旧在开始的位置,只是简单绘制到View上,是一个表面功夫。

而属性动画,则是实实在在的去改变了View的属性~!!!

Hello,属性动画

上面我们已经说过一些关于属性动画的常识,而下面,主要着重介绍使用方面内容。

实际上,属性动画就是针对于View去设置单独属性or组合不同属性设置从而达到动画效果。实质上属性动画即是更改View的实际属性。

使用之前,当然需要了解常用API,如下:

常用API

1. setTranslationX 和 setTranslationY:

这两个属性控制了View所处的位置,它们的值是由layout容器设置的,是相对于坐标原点(0,0左上角)的一个偏移量。

2. setRotation, setRotationX 和 setRotationY:

控制View绕着轴点(pivotX和pivotY)旋转。

3. setScaleX和 setScaleY:

控制View基于pivotX和pivotY的缩放。

4. setPivotX 和 setPivotY:

旋转的轴点和缩放的基准点,默认是View的中心点。

5. setX 和 setY:

描述了view在其父容器中的最终位置,是左上角左标和偏移量(translationX,translationY)的和。

6 setAlpha:

透明度,1是完全不透明,0是完全透明。

实际操作

下面我们将逐步进行讲解,当然是偏重点讲述。

1. setTranslationX() 使用

反手来一个简单属性动画:

private int position = 0;

// 简单属性动画
public void getTranslateX(View view) {
position += 100;
view.setTranslationX(position);
}

效果查看:


Android Study 之 属性动画初识_插值器_07

2. ObjectAnimator 使用

再来一个ObjectAnimator(动画效果大集合):

2.1 ofFloat:

// ObjectAnimator
public void getAnimation(View view) {
// 设置X轴平移
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationX", 300f);
// 设置动画时间
animator.setDuration(500);
animator.start();
}

效果如下:


Android Study 之 属性动画初识_属性动画_08

2.2 ofInt:

// ObjectAnimator ofInt
public void getObjectAnimatorInt(View view) {
ObjectAnimator animator = ObjectAnimator.ofInt(view, "backgroundColor", Color.RED, Color.YELLOW, Color.BLUE);
animator.setDuration(1000);
animator.start();
}

2.3 ofArgb:

// ObjectAnimator ofArgb
public void getObjectAnimatorArgb(View view) {
ObjectAnimator animator = ObjectAnimator.ofArgb(view, "backgroundColor", Color.RED, Color.YELLOW, Color.BLUE);
animator.setDuration(1000);
animator.start();
}

效果如下:


Android Study 之 属性动画初识_属性动画_09

3. 设置动画执行次数(模式)

很Easy,只需要组合搭配如下属性即可实现。

animator.setRepeatCount(INFINITE);
animator.setRepeatMode(INFINITE);

效果如下:


Android Study 之 属性动画初识_android_10

而所设置的常量所代表的含义如下:

/**
* 当动画执行完毕后,repeatCount为无限或正值时,动画将重新开始执行(循环)
*/
public static final int RESTART = 1;

/**
* 当动画执行完毕后,repeatCount为无限或正值时,动画将在每次迭代中进行反转方向
*/
public static final int REVERSE = 2;

/**
* 此值与setRepeatCount(int)属性一起使用,以无限地重复动画。
*/
public static final int INFINITE = -1;

4. 如何实现组合动画

/**
* 组合动画 实现方式一
*
* @param view
*/
public void getMoreAnimation1(final View view) {
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "HLQ_Blog", 300f);
animator.setDuration(500);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 动画执行中 会不断调用此方法
float value = (float) animation.getAnimatedValue();
view.setAlpha(value / 300);
view.setScaleX(value / 300);
view.setScaleY(value / 300);
}
});
animator.start();
}

public void getMoreAnimation2(final View view) {
ValueAnimator animator = ValueAnimator.ofFloat(0f, 300f);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// 动画执行中 会不断调用此方法
float value = (float) animation.getAnimatedValue();
view.setAlpha(value / 300);
view.setScaleX(value / 300);
view.setScaleY(value / 300);
}
});
animator.start();
}

public void getMoreAnimation3(View view) {
PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("alpha", 1f, 0f, 1f);
PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("scaleX", 1f, 0.7f, 1f);
PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0.7f, 1f);

ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view, holder1, holder2, holder3);
animator.setDuration(500);
animator.start();
}

public void getMoreAnimation4(View view) {
ObjectAnimator animator1 = ObjectAnimator.ofFloat(view, "alpha", 1f, 0.7f, 1f);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(view, "scaleX", 1f, 0.7f, 1f);
ObjectAnimator animator3 = ObjectAnimator.ofFloat(view, "scaleY", 1f, 0.7f, 1f);

AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(500);
animatorSet.play(animator1).after(animator2);
// 同步执行
// animatorSet.playTogether(animator1, animator2, animator3);
// 依次执行
// animatorSet.playSequentially(animator1, animator2, animator3);
animatorSet.start();

}

效果嘛,如下所示:


Android Study 之 属性动画初识_插值器_11

5. 实现抛物线效果

public void getMoreAnimation5(final View view) {
ValueAnimator animator = new ValueAnimator();
animator.setDuration(500);
// 设置默认
animator.setObjectValues(new PointF(0, 0));
// 开启 估值器 设定规则
animator.setEvaluator(new TypeEvaluator() {
@Override
public Object evaluate(float fraction, Object startValue, Object endValue) {
PointF pointF = new PointF();
pointF.x = 100f * (fraction * 4);
pointF.y = 0.5f * 100f * (fraction * 4) * (fraction * 4);
return pointF;
}
});
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
PointF pointF = (PointF) animation.getAnimatedValue();
view.setX(pointF.x);
view.setY(pointF.y);
}
});
animator.start();
}

插值器

这块比较有意思,单独作为一小节注明。

什么是插值器,简单举个例子:

小马要到小河对面,按照正常来讲,慢慢过去即可。 

But,

在过河期间,小马突然快跑起来,直到上岸过河。

在上面的例子中,小马本身可以慢慢过去即可,但是在过河期间,小马突然快跑起来,直到上岸。整个过程由于突然快跑而导致原有计划也就是慢慢走而被改变。So,你可以理解估值器,也就是在原有计划中插入特定属性,使其具有某些属性或者效果。

使用的时候也是很Easy,如下:

animator.setInterpolator(new 插值器);

下面依次图解说明已经提供好的插值器以及显示效果:

1. AccelerateInterpolator 加速插值器:


Android Study 之 属性动画初识_插值器_12

2. AccelerateDecelerateInterpolator 加速减速插值器:


Android Study 之 属性动画初识_属性动画_13

3. AnticipateOvershootInterpolator 插值器:


Android Study 之 属性动画初识_插值器_14

4. AnticipateInterpolator 回荡秋千插值器:


Android Study 之 属性动画初识_属性动画_15

5. BounceInterpolator 弹跳插值器:


Android Study 之 属性动画初识_插值器_16

6. CycleInterpolator 正弦周期变化插值器:


Android Study 之 属性动画初识_android_17

7. DecelerateInterpolator 减速插值器:


Android Study 之 属性动画初识_android_18

8. OvershootInterpolator:


Android Study 之 属性动画初识_插值器_19

GitHub查看地址

​​https://github.com/HLQ-Struggle/AndroidAnimation​​

举报

相关推荐

0 条评论