视图动画:
AlphaAnimation、RotateAnimation、TranslateAnimation、ScaleAnimation 和 动画集:AnimationSet
- AlphaAnimation(透明度动画):
AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
alphaAnimation.setDuration(1000);
view.startAnimation(alphaAnimation);
- RotateAnimation(旋转动画):
RotateAnimation rotateAnimation = new RotateAnimation(0, 360,
RotateAnimation.RELATIVE_TO_SELF, 0.5F, RotateAnimation.RELATIVE_TO_SELF, 0.5F);
rotateAnimation.setDuration(1000);
view.startAnimation(rotateAnimation);
- TranslateAnimation(位移动画):
TranslateAnimation translateAnimation = new TranslateAnimation(0, 200, 0, 0);
translateAnimation.setDuration(1000);
view.startAnimation(translateAnimation);
- ScaleAnimation(缩放动画):
ScaleAnimation scaleAnimation = new ScaleAnimation(0, 1, 0, 1,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(1000);
view.startAnimation(scaleAnimation);
- AnimationSet(动画集合):
AnimationSet animationSet = new AnimationSet(true);
animationSet.setDuration(4000);
animationSet.addAnimation(alphaAnimation);
animationSet.addAnimation(rotateAnimation);
animationSet.addAnimation(translateAnimation);
animationSet.addAnimation(scaleAnimation);
animationSet.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Log.e(TAG, "onAnimationStart: 动画开始执行的时候调用");
}
@Override
public void onAnimationEnd(Animation animation) {
Log.e(TAG, "onAnimationEnd: 动画结束执行的时候调用");
}
@Override
public void onAnimationRepeat(Animation animation) {
Log.e(TAG, "onAnimationRepeat: 动画重复执行的时候调用");
}
});
//启动动画
view.startAnimation(animationSet);
属性动画
PropertyValuesHolder、Animator、ObjectAnimator 、ValueAnimator
- ObjectAnimator :
ObjectAnimator 是属性动画框架中最重要的实行类,创建一个ObjectAnimator只需要通过它的静态工厂类直接返回一个ObjectAnimator对象.(通过ofxxx方法);
必须具备get 、set方法,不然ObjectAnimator就无法起效;
- 1.translationX 和 translationY:控制view对象从布局容器的左下方坐标偏移的位置;
- 2.rotation 、rotationX 和 rotationY:控制view对象围绕它的支点进行2D和3D旋转;
- 3.scaleX 和 scaleY: 控制view对象围绕它的支点进行2D缩放;
- 4.pivotX 和 pivotY:这两个属性控制着View对象的支点位置, 围绕这个支点进行旋转和缩放变换处理;
默认情况下,该支点的位置就是view的中心点;- 5.alpha:它表示view对象的alpha透明度,默认值是1(不透明) ,0代表完全透明(不可见);
如果没有get set方法,那么可以自定义一个属性或者包装类,来间接地给这个属性增加get set方法, 或者通过ValueAnimator来实现;
- 自带属性:
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, "translationX", 200);
objectAnimator.setDuration(1000);
objectAnimator.start();
ObjectAnimator animatorColor = ObjectAnimator.ofInt(view,"BackgroundColor",0xffff0000,0xff00ff00);
animatorColor.setEvaluator(new ArgbEvaluator());
animatorColor.setDuration(1000);
animatorColor.start();
- 自定义属性:
public class WrapperView {
private View view;
public WrapperView(View view) {
this.view =view;
}
public int getWidth(){
return view.getLayoutParams().width;
}
public void setWidth(int width) {
view.getLayoutParams().width = width;
view.requestLayout();
}
}
WrapperView wrapperView = new WrapperView(tvWrapper);
ObjectAnimator objectAnimatorWrapper = ObjectAnimator.ofInt(wrapperView, "width", 100).setDuration(1000);
objectAnimatorWrapper.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
Log.e(TAG, "onAnimationStart: 动画开始执行的时候调用");
}
@Override
public void onAnimationEnd(Animator animation) {
//这个应该是用得最多的吧
Log.e(TAG, "onAnimationEnd: 动画结束执行的时候调用");
}
@Override
public void onAnimationCancel(Animator animation) {
Log.e(TAG, "onAnimationEnd: 动画取消执行的时候调用");
}
@Override
public void onAnimationRepeat(Animator animation) {
Log.e(TAG, "onAnimationEnd: 动画重复执行的时候调用");
}
});
objectAnimatorWrapper.start();
- PropertyValuesHolder:
类似AnimationSet
- 动画合并:
PropertyValuesHolder valuesHolderTranslastion = PropertyValuesHolder.ofFloat("translationX", 100f);
PropertyValuesHolder valuesHolderScaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f, 0.3f);
PropertyValuesHolder valuesHolderScaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f, 0.3f);
PropertyValuesHolder valuesHolderColor = PropertyValuesHolder.ofInt("BackgroundColor", 0xff888888, 0xff00ff00);
ObjectAnimator objectAnimatorProper = ObjectAnimator.ofPropertyValuesHolder(tvObjProperty, valuesHolderTranslastion, valuesHolderScaleX, valuesHolderScaleY, valuesHolderColor);
objectAnimatorProper.setDuration(1000);
objectAnimatorProper.start();
- 动画拆分:
// 在 0% 处开始向X移动
Keyframe keyframe1 = Keyframe.ofFloat(0, 0);
// 时间经过 50% 的时候,动画完成度 100%
Keyframe keyframe2 = Keyframe.ofFloat(0.5f, 100);
// 时间见过 100% 的时候,动画完成度倒退到 0%位置
Keyframe keyframe3 = Keyframe.ofFloat(1, 0);
PropertyValuesHolder holder = PropertyValuesHolder.ofKeyframe("translationX", keyframe1, keyframe2, keyframe3);
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(tvObjPropertyKey, holder);
animator.start();
- ValueAnimator:
ValueAnimator 是 ObjectAnimator 的父类,ValueAnimator 就是一个不能指定目标对象版本的 ObjectAnimator
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0,1000);
valueAnimator.setTarget(view);
valueAnimator.setDuration(1000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// TODO: 2018/10/24
float value = (float) animation.getAnimatedValue();
if (value==500f){
ScaleAnimation scaleAnimation = new ScaleAnimation(0, 1, 0, 1, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(100);
view.startAnimation(scaleAnimation);
}
}
});
- Animator:
在
res/animator
下创建布局文件,代码加载xml布局文件
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:propertyName="scaleX"
android:valueFrom="1.0"
android:valueTo="2.0"
android:valueType="floatType">
</objectAnimator>
Animator animatorXml = AnimatorInflater.loadAnimator(MainActivity.this,R.animator.animator_xml);
animatorXml.setTarget(view);
animatorXml.start();
AnimationUtils (工具类)
- Android SDK 提供的工具类:
返回值 | 公共方法 | 描述 |
---|---|---|
static long | currentAnimationTimeMillis() | 以毫秒返回当前动画时间 |
static Animation | loadAnimation(Context context, int id) | 从资源加载动画对象 |
static Interpolator | loadInterpolator(Context context, int id) | 从资源中加载内插器对象 |
static LayoutAnimationController | loadLayoutAnimation(Context context, int id) | 从资源加载动画对象(返回值不同) |
static Animation | makeInAnimation(Context c, boolean fromLeft) | 用布尔参数决定滑入的方向是左侧还是右侧向上 |
static Animation | makeInChildBottomAnimation(Context c) | 视图总是从屏幕的底部向上滑入 |
static Animation | makeOutAnimation(Context c, boolean toRight) | 用布尔参数决定滑入的方向是左侧还是右侧 |
animation = AnimationUtils.loadAnimation(this, R.anim.animation_utils);
view.startAnimation(animation);
ViewAnimationUtils (5.X的工具类)
createCircularReveal(View view, int centerX, int centerY, float startRadius, float endRadius)
- centerX : 中心点X坐标;
- centerY : 中心点Y坐标;
- startRadius: 动画圆的起始半径;
- endRadius: 动画圆的结束半径.
ViewAnimationUtils.createCircularReveal(ImageView, centerX, centerY, mImageView.getWidth(), 0);
Interpolator(插值器)
Interpolator 其实就是速度设置器。你在参数里填入不同的 Interpolator ,动画就会以不同的速度模型来执行;Google TimeInterpolator
- AccelerateDecelerateInterpolator:
先加速再减速。这是默认的 Interpolator;
- LinearInterpolator:
匀速;
- AccelerateInterpolator:
持续加速;
- DecelerateInterpolator:
以最高速开始,持续减速直到停止;
- AnticipateInterpolator:
先回退一下段,然后再正常运动;
- OvershootInterpolator:
到终点的时候超出一下段,然后弹回来;
- AnticipateOvershootInterpolator:
开始前回拉,最后超过一些然后回弹;
- BounceInterpolator:
到达终点的时候弹回来两下,然后回到终点;
- CycleInterpolator:
这个也是一个正弦 / 余弦曲线,不过它和 AccelerateDecelerateInterpolator 的区别是,它可以自定义曲线的周期,所以动画可以不到终点就结束,也可以到达终点后回弹,回弹的次数由曲线的周期决定,曲线的周期由 CycleInterpolator() 构造方法的参数决定。
- PathInterpolator:
自定义动画完成度 / 时间完成度曲线。
用这个 Interpolator 你可以定制出任何你想要的速度模型。定制的方式是使用一个 Path 对象来绘制出你要的动画完成度 / 时间完成度曲线
- FastOutLinearInInterpolator(5.0以上):
贝塞尔曲线的持续加速的运动路线,AccelerateInterpolator比FastOutLinearInInterpolator斜率要低一点;
- FastOutSlowInInterpolator(5.0以上):
贝塞尔曲线,前期加速度要快得多;
- LinearOutSlowInInterpolator(5.0以上):
减速曲线,初始速度更高;
SVG(矢量动画)
-
Android 5.X增加了对SVG矢量图的支持(VectorDrawable,AnimatedVectorDrawable):
<path>标签支持的指令:
- M: 移动 moveTo;
- L: 直线;
- H: 水平线;
- V: 垂直线;
- C: 三次贝塞尔曲线;
- S: 三次贝塞尔曲线;
- Q: 二次贝塞尔曲线;
- T: 映射前面路径后的终点;
- Z: 关闭路径;
- A: 弧线;
- RX,RY表示椭圆半圆的半轴大小;
- XROTATION表示X轴与水平方向的顺时针方向的夹角;
- FLAG1有两个值:1.表示大角度的弧线,0.表示小角度弧线;
- FLAG2有两个值,确定从起点至终点的方向:1.表示顺时针,0.表示逆时针;
- X,Y轴为终点坐标;
1.大小写效果一样,2.坐标轴和canvas一样左上角(0,0),3.指令和数据间的空格可以省略,4.同个指令出现多个时候可以只用一个。
defaultConfig {
//配置信息
vectorDrawables.useSupportLibrary = true
}
<!--res/drawable下新建-->
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="100dp"
android:width="100dp"
android:viewportWidth="100"
android:viewportHeight="100">
<group>
<path
android:name="path1"
android:strokeColor="@color/colorPrimaryDark"
android:strokeWidth="5"
android:strokeLineCap="round"
android:pathData="M 20,80 L 50,80 80,80"/>
</group>
<group>
<path
android:name="path2"
android:strokeColor="@color/colorPrimaryDark"
android:strokeWidth="5"
android:strokeLineCap="round"
android:pathData="M 20,20 L 50,20 80,20"/>
</group>
</vector>
<!--res/animator下新建-->
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="pathData"
android:valueFrom="M 20,80 L 50,80 80,80"
android:valueTo="M 20,80 L 50,50 80,80"
android:valueType="pathType"
android:interpolator="@android:anim/bounce_interpolator">
</objectAnimator>
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="pathData"
android:valueFrom="M 20,20 L 50,20 80,20"
android:valueTo="M 20,20 L 50,50 80,20"
android:valueType="pathType"
android:interpolator="@android:anim/bounce_interpolator">
</objectAnimator>
<!--res/drawble-v21下新建-->
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/svg_line">
<target
android:name="path1"
android:animation="@animator/animator_svg_path1"/>
<target
android:name="path2"
android:animation="@animator/animator_svg_path2"/>
</animated-vector>
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Drawable drawable = imageViewSVG.getDrawable();
if (drawable instanceof Animatable){
((Animatable) drawable).start();
}
}