Android动画总结

Android动画总结

基础动画

  • 平移动画Translation

实现方式一:

xml编写平移动画
base_anim_translation.xml
<?xml version="1.0" encoding="utf-8"?>
<translate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:toXDelta="200"
    android:toYDelta="200"
    android:duration="500"
    android:fillAfter="true">
</translate>

代码加载执行动画:
Animation animation = AnimationUtils.loadAnimation(this,R.anim.base_anim_translation);
button.startAnimation(animation);

实现方式二:

TranslateAnimation translateAnimation = new TranslateAnimation(0,200,0,200);
translateAnimation.setDuration(500);//设置执行时间
translateAnimation.setFillAfter(true);
button.startAnimation(translateAnimation);
  • 旋转动画Rotation

实现方式一:

xml编写旋转动画
base_anim_rotation.xml
<?xml version="1.0" encoding="utf-8"?>
<rotate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:toDegrees="90"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="500"
    android:fillAfter="true">
</rotate>

代码加载执行动画:
Animation animation = AnimationUtils.loadAnimation(this,R.anim.base_anim_rotation);
button.startAnimation(animation);

实现方式二:

RotateAnimation rotateAnimation = new RotateAnimation(0,90,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
rotateAnimation.setDuration(500);
rotateAnimation.setFillAfter(true);
button.startAnimation(rotateAnimation);
  • 缩放动画Scale

实现方式一:

xml编写缩放动画 
base_anim_scale.xml
<?xml version="1.0" encoding="utf-8"?>
<scale
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXScale="1"
    android:fromYScale="1"
    android:toXScale="2"
    android:toYScale="2"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="500"
    android:fillAfter="true">
</scale>

代码加载执行动画:
Animation animation = AnimationUtils.loadAnimation(this,R.anim.base_anim_scale);
button.startAnimation(animation);

实现方式二:

RotateAnimation rotateAnimation = new RotateAnimation(0,90,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
rotateAnimation.setDuration(500);
rotateAnimation.setFillAfter(true);
button.startAnimation(rotateAnimation);
  • 透明度动画Alpha

实现方式一:

xml编写透明度动画
base_anim_alpha.xml
<?xml version="1.0" encoding="utf-8"?>
<alpha
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromAlpha="1"
    android:toAlpha="0.2"
    android:duration="500"
    android:fillAfter="true">
</alpha>

代码加载执行动画:
Animation animation = AnimationUtils.loadAnimation(this,R.anim.base_anim_alpha);
button.startAnimation(animation);

实现方式二:

AlphaAnimation alphaAnimation = new AlphaAnimation(1f,0.2f);
alphaAnimation.setDuration(500);
alphaAnimation.setFillAfter(true);
button.startAnimation(alphaAnimation);
  • 帧动画

实现方式一:

xml编写帧动画
anim_list.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">

    <item
        android:drawable="@drawable/anim_1"
        android:duration="200"/>
    <item
        android:drawable="@drawable/anim_2"
        android:duration="200"/>
    <item
        android:drawable="@drawable/anim_3"
        android:duration="200"/>
    <item
        android:drawable="@drawable/anim_4"
        android:duration="200"/>
</animation-list>

布局:
<ImageView
    android:id="@+id/iv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
    
获取背景实现动画:
AnimationDrawable drawable = (AnimationDrawable) iv.getBackground();
if(drawable.isRunning()){
    drawable.stop();
}else {
    drawable.start();
}

实现方式二:

代码实现方式:
AnimationDrawable animationDrawable = new AnimationDrawable() ;
int[] ids = {R.drawable.anim_1,R.drawable.anim_2,R.drawable.anim_3,R.drawable.anim_4};
//通过循环将每一帧添加到AnimationDrawable中
for(int i = 0 ; i < ids.length ; i ++){
    Drawable frame = getResources().getDrawable(ids[i]);
    animationDrawable.addFrame(frame,200);
}
animationDrawable.setOneShot(false);
iv.setBackground(animationDrawable);
animationDrawable.start();

属性动画

###ObjectAnimator

  • 平移动画
实现方式一:
button.animate().translationX(200).setDuration(500).translationY(200).start();

实现方式二:
ObjectAnimator animator = ObjectAnimator.ofFloat(button,"translationX",200);
animator.setDuration(500);
animator.start();
  • 旋转动画
ObjectAnimator animator = ObjectAnimator.ofFloat(button,"rotation",90);
animator.setDuration(500);
animator.start();
  • 缩放动画
ObjectAnimator animator = ObjectAnimator.ofFloat(button,"scaleX",2);
animator.setDuration(500);
animator.start();
  • 透明度动画
ObjectAnimator animator = ObjectAnimator.ofFloat(button,"alpha",0.2f);
animator.setDuration(500);
animator.start();
  • PropertyValuesHolder改变多个属性值
PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("translationX",200);
PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("translationY",200);

ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(button, holder1, holder2);
animator.setDuration(500);
animator.start();
  • 关键帧动画
Keyframe frame1 = Keyframe.ofFloat(0,0);
Keyframe frame2 = Keyframe.ofFloat(0.5f,200);
Keyframe frame3 = Keyframe.ofFloat(1,100);
//将关键帧应用到属性上
PropertyValuesHolder holder = PropertyValuesHolder.ofKeyframe("translationX", frame1, frame2, frame3);

ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(button, holder);
animator.setDuration(500);
animator.start();
  • 补间器(差值器)

1、系统自带的补间器

Interpolator资源ID功能
AccelerateDecelerateInterpolator@android:anim/accelerate_decelerate_interpolator先加速再减速
AccelerateInterpolator@android:anim/accelerate_interpolator加速
AnticipateInterpolator@android:anim/anticipate_interpolator先后退一小步然后加速前进
AnticipateOvershootInterpolator@android:anim/anticipate_overshoot_interpolator先后退一小步再加速前进,超出终点一小步再回到终点
BounceInterpolator@android:anim/bounce_interpolator最后阶段弹球效果
CycleInterpolator@android:anim/cycle_interpolator周期运行
DecelerateInterpolator@android:anim/decelerate_interpolator减速
LinearInterpolator@android:anim/linear_interpolator匀速
OvershootInterpolator@android:anim/overshoot_interpolator快速到达终点并超出一小步然后回到终点

2、平移动画补间器示例

ObjectAnimator animator = ObjectAnimator.ofFloat(button,"translationX", 100,400);
animator.setDuration(500);
//先后退一小步再加速前进,超出终点一小步再回到终点
animator.setInterpolator(new AnticipateOvershootInterpolator());
animator.start();

3、自定义补间器

 采用上面创建的ObjectAnimator
 animator.setInterpolator(new TimeInterpolator() {
    @Override
    public float getInterpolation(float input) {
        //input 百分比(范围 0 - 1 ) 0.1 0.3 0. 5 只与时间有关
        //上面我们定义动画执行时间是500  如果过了200  input=0.4
        // 与自己设定的值无关 只与时间有关
        Log.i("ObjeceAnimator","interpolation result :"+(1 - input));
        return 1 - input;// 1 ---- 0 我们可以根据input自定义返回值
    }
});
  • Evaluator计算规则

Evaluator是计算规则,系统提供了一些默认的计算规则(FloatEvaluator IntEvaluator)

自定义计算规则
animator.setEvaluator(new TypeEvaluator<Float>() {
    @Override
    public Float evaluate(float fraction, Float startValue, Float endValue) {
		//在这个方法里,我们可以任意的自定义计算规则
        float result = startValue + (endValue - startValue) * fraction ;
        Log.i("ObjeceAnimator","evaluator fraction:"+fraction+",result:"+result);
        return result ;
    }
});
  • 动画监听
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator valueAnimator) {
        float fraction = valueAnimator.getAnimatedFraction();
        float value = (float) valueAnimator.getAnimatedValue();
        Log.i("ObjeceAnimator","update fraction:"+fraction+",value:"+value);
    }
});

Interpolation 中的getInterpolation方法的返回值 负责计算百分比 只和时间有关
Evaluator 中的evaluate方法根据百分比和开始结束值计算value
UpdateListener中的fraction和value都是上面计算的结果
ValueAnimator是动画基础,可以在此基础上完成想要的任何动画

  • ValueAnimator

ValueAnimator只提供变化量,并不真正的作用于view上
ValueAnimator根据补间器Interpolator(差值器)时间产生百分比
ValueAnimator根据Evaluator的计算规则和第2步中的百分比,计算value值
ValueAnimator中的UpdateListener监听获取百分比和value

ValueAnimator animator = ValueAnimator.ofFloat(100,200);
animator.setDuration(500);
animator.start();
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        float fraction = animation.getAnimatedFraction();
        float value = (float) animation.getAnimatedValue();
		   //在这里设置动画属性
        button.setTranslationX(value);
        Log.i("ObjectAnimator","fraction:"+fraction+",value:"+value);
    }
});
  • ValueAnimator.ofObject使用

Evaluator作用:提供计算规则
强调:无论什么类型都需要计算规则Evaluator
ofFloat:系统默认提供FloatEvaluator
ofInt:系统默认提供IntEvaluator
ofObject:系统不知道使用的具体类型,同时又需要计算规则,这时就需要我们自己提供计算规则

ValueAnimator animator = ValueAnimator.ofObject(new CharEvaluator(),new Character('a'),new Character('z'));
animator.setDuration(10000);
animator.start();

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        char value = (char) animation.getAnimatedValue();
        button.setText("测试"+value);
    }
});
  • AnimatorSet
AnimatorSet animatorSet = new AnimatorSet() ;
ObjectAnimator animator1 = ObjectAnimator.ofFloat(testBtn,"translationX",200);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(testBtn,"translationY",200);
animatorSet.play(animator1);
//依次执行动画
animatorSet.playSequentially(animator1,animator2);
//同时执行动画
//animatorSet.playTogether(animator1,animator2);

animatorSet.setDuration(500);
animatorSet.start();

矢量动画

  • SVG

1、 SVG Path指令
M = moveto(M X,Y) :将画笔移动到指定的坐标位置
L = lineto(L X,Y) :画直线到指定的坐标位置
H = horizontal lineto(H X):画水平线到指定的X坐标位置
V = vertical lineto(V Y):画垂直线到指定的Y坐标位置
C = curveto(C X1,Y1,X2,Y2,ENDX,ENDY):三次贝赛曲线
S = smooth curveto(S X2,Y2,ENDX,ENDY)
Q = quadratic Belzier curve(Q X,Y,ENDX,ENDY):二次贝赛曲线
T = smooth quadratic Belzier curveto(T ENDX,ENDY):映射
A = elliptical Arc(A RX,RY,XROTATION,FLAG1,FLAG2,X,Y):弧线
Z = closepath():关闭路径

2、 SVG动画示例

1、 定义VectorDrawable
drawable文件夹下定义search_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="150dp"
    android:height="24dp"
    android:viewportWidth="150"
    android:viewportHeight="24">

    <!-- 搜索按钮-->
    <path
        android:name="search"
        android:pathData="M141,17 A9,9 0 1,1 142,16 L149,23"
        android:strokeWidth="2"
        android:strokeColor="#ffffff"
        android:strokeAlpha="0.8"
        android:strokeLineCap="round" />

    <!-- 底部线条 -->
    <path
        android:name="bar"
        android:pathData="M0,23 L149,23"
        android:strokeWidth="2"
        android:strokeColor="#ffffff"
        android:strokeAlpha="0.8"
        android:strokeLineCap="square" />
</vector>

2、定义animated-vector
animated-vector相当于一个桥梁,将动画与VectorDrawable连接在一起

drawable文件夹下定义search_to_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<animated-vector
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/search_bar">

    <target
        android:animation="@animator/anim_search_none"
        android:name="search" />

    <target
        android:animation="@animator/anim_bar_fill"
        android:name="bar" />
</animated-vector>

drawable文件夹下定义bar_to_search.xml
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/search_bar" >

    <!-- animated-vector 相当于是一个桥梁  静态的svg和动画连接的桥梁 -->
    <target
        android:animation="@animator/anim_search_fill"
        android:name="search"/>
    <target
        android:animation="@animator/anim_bar_none"
        android:name="bar"/>
</animated-vector>

3、定义动画
animator文件加下定义anim_bar_fill.xml和anim_bar_none.xml、anim_search_fill.xml、anim_search_none.xml

anim_bar_fill.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="trimPathEnd"
    android:valueFrom="0"
    android:valueTo="1"
    android:valueType="floatType"
    android:duration="500" />
    
anim_bar_none.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="trimPathEnd"
    android:valueFrom="1"
    android:valueTo="0"
    android:valueType="floatType"
    android:duration="500" />  
    
anim_search_fill.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:propertyName="trimPathEnd"
    android:valueFrom="0"
    android:valueTo="1"
    android:valueType="floatType" />
    
anim_search_none.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="trimPathEnd"
    android:valueFrom="1"
    android:valueTo="0"
    android:valueType="floatType"
    android:duration="500" />
    
4、动画使用
public class SvgActivity extends AppCompatActivity {
    private ImageView search ;
    private Boolean flag = false ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_svg);

        search = (ImageView) findViewById(R.id.search);

        final AnimatedVectorDrawable barToSearch = (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.bar_to_search);
        final AnimatedVectorDrawable searchToBar = (AnimatedVectorDrawable) getResources().getDrawable(R.drawable.search_to_bar);

        search.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(flag) {
                    search.setImageDrawable(barToSearch);
                    barToSearch.start();
                    flag = false ;
                }else {
                    search.setImageDrawable(searchToBar);
                    searchToBar.start();
                    flag = true ;
                }
            }
        });
    }
}  
  • 第三方动画框架Lottie

Lottie使用同一个JSON动画文件,可在不同平台实现相同的效果。

GitHub地址

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值