动画

作者: 要学的东西太多了 | 来源:发表于2018-10-08 11:13 被阅读0次

    1.View动画XML文件有固定语法,如下:

    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@anim/out"
        android:shareInterpolator="true">
    </set>
    

    set动画集合里面可以包含若干动画,也可以嵌套其他动画集合。interpolator表示动画集合的插值器,影响动画的速度。shareInterpolator表示set动画集合中的动画和其他集合是否共享一个插值器。如果父set集合不指定插值器,子动画或子集合就得自己指定或使用默认的。

    2.平移动画用translate标签,如下:

    <translate android:fromXDelta="100"
            android:toXDelta="0"
            android:fromYDelta="0"
            android:toYDelta="100"/>
    

    其中,fromXDelta表示x的起始值,toXDelta表示x的结束值,fromYDeltatoYDelta表示y方向的,按照android坐标系,右、下为正

    3.缩放动画用scale标签,如下:

    <scale android:fromXScale="2%"
            android:toXScale="30%"
            android:fromYScale="0"
            android:toYScale="50%"
            android:pivotX="10"
            android:pivotY="30"
            android:duration="3000"/>
    

    其中,fromXScale表示水平方向缩放的初始值,toXScale为结束值;fromYScaletoYScale表示竖直方向的;pivotX表示缩放轴点的x坐标,pivotY表示缩放轴点的y坐标,轴点的坐标影响缩放效果,比如pivotXView的左边界,那么就会向右缩放,而默认的pivotXView的左上角。取值都有三种,具体数值(缩放起点为View左上角坐标加具体数值像素),百分比(在当前View左上角坐标加上View宽度的具体百分比),百分比+p(在View左上角坐标加上父控件宽度的具体百分比)。

    4.旋转动画用rotate标签,如下:

    <rotate android:fromDegrees="100"
            android:toDegrees="80"
            android:pivotY="50"
            android:pivotX="50"/>
    

    其中,fromDegrees表示旋转开始的角度,toDegrees表示旋转结束的角度,pivotY表示旋转轴点的y坐标,pivotX表示旋转轴点的x坐标,轴点的坐标影响缩放效果,比如View绕着自己的某个角旋转和绕中心旋转效果肯定不一样,默认是绕着view的左上角旋转。

    5.透明度动画用alpha标签,如下:

    <alpha android:fromAlpha="0.1"
            android:toAlpha="0.9"/>
    

    其中,fromAlpha表示透明度的起始值,toAlpha表示透明度的结束值,范围0.0-1.0。

    6.上述四种动画都有以下两个属性,android:duration表示动画持续的时间,单位毫秒;android:fillAfter表示动画结束后View是否停留在结束的位置,注意fillAfter必须加在set标签里面才起作用。

    7.动画的应用分xml文件应用和代码应用。如下:

    XML动画应用:
    Animation animation = AnimationUtils.loadAnimation(context,R.anim.animation);
            animation.setDuration(300);
            button.startAnimation(animation);
    
    代码应用:
    Animation animation = new AlphaAnimation(0,1);
            animation.setDuration(300);
            button.startAnimation(animation);
    

    8.通过animation.setAnimationListener(animationListener)方法可以给动画设置监听,animationListener内部包含如下回调方法:

    void onAnimationStart(Animation animation);//开始动画
    void onAnimationEnd(Animation animation);//结束动画
    void onAnimationRepeat(Animation animation);//重复动画
    

    9.帧动画用animation-list标签,系统提供AnimationDrawable来使用帧动画,如下:

    <?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/shape" android:duration="100"/>
        <item android:drawable="@drawable/shape_round1" android:duration="100"/>
        <item android:drawable="@drawable/shape_round2" android:duration="100"/>
        <item android:drawable="@drawable/shape_round3" android:duration="100"/>
    </animation-list>
    
    button.setBackgroundResource(R.drawable.animation_list);
            AnimationDrawable animationDrawable = (AnimationDrawable) button.getBackground();
            animationDrawable.start();
    

    需要注意的是,不要使用过多过大的图片资源,否则会造成OOM。

    10.layoutAnimation用于为ViewGroup指定动画,这样它的子元素出场时就有了这种动画,如下:

    <?xml version="1.0" encoding="utf-8"?>
    <layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
        android:delay="0.5"
        android:animationOrder="normal"
        android:animation="@anim/out">
    
    </layoutAnimation>
    

    其中,delay表示子元素开始动画的延时系数,比如delay为0.5,这个动画的周期为100ms,那么第一个子元素的入场延时为50ms,第二个延时100ms,以此类推。
    animationOrder表示子元素动画的顺序,分为:normal(顺序),reverse(逆序),random(随机)。
    animation表示为子元素指定的动画。

    layoutAnimation的使用方法有两种:一种是在xml文件的ViewGroup里面指定android:layoutAnimation属性;一种是在代码里使用,如下:

    Animation layoutAnimation = AnimationUtils.loadAnimation(this,R.anim.out);
            LayoutAnimationController controller = new LayoutAnimationController(layoutAnimation);
            controller.setDelay(0.5f);
            controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
            listView.setLayoutAnimation(controller);
    

    11.Activity的切换动画,通过activity.overridePendingTransition(inAnimId, outAnimId)方法来实现,inAnimId表示Activity被打开时所需的动画资源id,outAnimId表示Activity被暂停时所需的动画资源id。需要注意的是,这个方法必须在startActivity()activity.finish()后调用,不然无法生效。
    Fragment切换可以通过transaction.setCustomAnimations()方法设置动画效果,注意这个动画必须是View动画。

    12.属性动画可以对任何对象的属性进行动画,注意是任何对象,动画默认时间间隔300ms,默认帧率10ms/帧。开源动画库nineoldandroids可以兼容API11以前的版本。建议在代码中使用属性动画,xml中定义的属性动画可能无法明确初始值。XML使用方式如下:

    AnimatorSet set = AnimatorInflater.loadAnimator(context,animationResId);
            set.setTarget(button);
            set.start();
    

    13.ObjectAnimatorValueAnimator的子类,使用如下:

    ObjectAnimator objectAnimator = new ObjectAnimator();
            objectAnimator.setTarget(button);//目标对象
            objectAnimator.setPropertyName("translationX");//改变的属性
            objectAnimator.setFloatValues(-100f);//改变属性的变化值集合
            objectAnimator.setDuration(1000);//时间间隔,单位ms
            objectAnimator.setRepeatCount(-1);//循环次数,默认为0,-1表示无限循环
            objectAnimator.setRepeatMode(ObjectAnimator.REVERSE);//循环模式,RESTART表示每次完了都从头开始,REVERSE表示每次完了后会倒过来播放
            objectAnimator.start();
    

    14.ValueAnimator的使用如下:

    ValueAnimator valueAnimator = ObjectAnimator.ofInt(button,"backgroundColor",0xffffffff,0x00000000);
            valueAnimator.setDuration(3000);
            valueAnimator.setEvaluator(new ArgbEvaluator());
            objectAnimator.setRepeatCount(100);//循环次数,默认为0,-1表示无限循环
            objectAnimator.setRepeatMode(ObjectAnimator.REVERSE);//循环模式,RESTART表示每次完了都从头开始,REVERSE表示每次完了后会倒过来播放
            valueAnimator.start();
    

    15.AnimatorSet使用如下:

    AnimatorSet animatorSet = new AnimatorSet();
            //子动画同时播放
            animatorSet.playTogether(
                    ObjectAnimator.ofFloat(button,"translationX",-100),
                    ObjectAnimator.ofFloat(button,"rotationX",0,300)
            );
            //子动画按先后顺序播放
            animatorSet.playSequentially(
                    ObjectAnimator.ofFloat(button,"translationX",-100),
                    ObjectAnimator.ofFloat(button,"rotationX",0,300)
            );
            animatorSet.setDuration(30000);
            animatorSet.start();
    

    16.TimeInterpolator(插值器)常用的有LinearInterpolator(线性插值器,用于匀速动画),AccelerateDecelerateInterpolator(加速减速插值器,动画两头慢,中间快),DecelerateInterpolator(减速插值器,动画越来越慢)。TypeEvaluator(估值器)常用的有IntEvaluator(整型估值器),FloatEvaluator(浮点型估值器),ArgbEvaluator(颜色估值器)。

    17.属性动画要求动画作用的对象必须提供要改变的属性有效的get、set方法,否则可能没效果(该属性set方法没有实际改变UI效果)或者直接crash(该属性没有get、set方法)。

    18.动画应用注意事项:

    1.注意OOM问题,特别是帧动画。
    2.属性动画如果是无限循环的,那么在activity销毁的时候一定要调用动画的cancel方法。
    3.View动画是对View的影像动画,并不是真正改变View的状态,有时setVisibility方法会失效,在之前调用clearAnimation方法可以解决。
    4.View动画的点击等监听事件,在动画完成后,监听事件还是原来的位置,因为动画的只是影像。
    

    示例代码:

    public class AnimationActivity extends AppCompatActivity {
    
        @BindView(R.id.button1)
        Button button1;
        @BindView(R.id.button2)
        Button button2;
        @BindView(R.id.button3)
        Button button3;
        @BindView(R.id.button4)
        Button button4;
        @BindView(R.id.button5)
        Button button5;
        @BindView(R.id.button6)
        Button button6;
        @BindView(R.id.button7)
        Button button7;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_animation);
            ButterKnife.bind(this);
        }
    
        @OnClick({R.id.button1, R.id.button2, R.id.button3, R.id.button4, R.id.button5, R.id.button6, R.id.button7})
        public void onViewClicked(View view) {
            switch (view.getId()) {
                case R.id.button1:
                    showAlpha();
                    break;
                case R.id.button2:
                    showRotate();
                    break;
                case R.id.button3:
                    showScale();
                    break;
                case R.id.button4:
                    showTranslate();
                    break;
                case R.id.button5:
                    showObjectAnimator();
                    break;
                case R.id.button6:
                    showValueAnimator();
                    break;
                case R.id.button7:
                    showAnimatorSet();
                    break;
            }
        }
    
        private void showAlpha(){
            Animation animation = AnimationUtils.loadAnimation(this,R.anim.alpha);
            button1.startAnimation(animation);
        }
    
        private void showRotate(){
            Animation animation = AnimationUtils.loadAnimation(this,R.anim.rotate);
            button2.startAnimation(animation);
        }
    
        private void showScale(){
            Animation animation = AnimationUtils.loadAnimation(this,R.anim.scale);
            button3.startAnimation(animation);
        }
    
        private void showTranslate(){
            Animation animation = AnimationUtils.loadAnimation(this,R.anim.translate);
            button4.startAnimation(animation);
        }
    
        private void showObjectAnimator(){
            ObjectAnimator animator= ObjectAnimator.ofFloat(button5,"translationY",10,20,30,20,10,0,-10,-20,-30,-20,-10,0);
            animator.setDuration(3000);
            animator.start();
        }
    
        private void showValueAnimator(){
            ValueAnimator animator = ObjectAnimator.ofInt(button6,"backgroundColor",0xffffffff,0xff000000);
            animator.setDuration(3000);
            animator.setEvaluator(new ArgbEvaluator());
            animator.start();
        }
    
        private void showAnimatorSet(){
            ObjectAnimator animator1= ObjectAnimator.ofFloat(button7,"translationX",0,20,40,60,80,100,120);
            animator1.setDuration(3000);
            ObjectAnimator animator2= ObjectAnimator.ofFloat(button7,"translationY",0,-10,-20,-30,-40,-50);
            animator2.setDuration(3000);
            ObjectAnimator animator3= ObjectAnimator.ofInt(button7,"backgroundColor",0xffff0000,0xff0000ff);
            animator3.setEvaluator(new ArgbEvaluator());
            animator3.setDuration(3000);
            AnimatorSet set = new AnimatorSet();
            set.playSequentially(animator1,animator2,animator3);
            set.start();
        }
    }
    

    xml文件:

    平移动画
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:fillAfter="true">
        <translate android:fromXDelta="0"
            android:toXDelta="280"
            android:fromYDelta="0"
            android:toYDelta="-60"
            android:duration="3000"/>
    </set>
    
    缩放动画
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:fillAfter="true">
        <scale android:fromXScale="0"
            android:toXScale="80%"
            android:fromYScale="0"
            android:toYScale="50%"
            android:pivotX="10"
            android:pivotY="30"
            android:duration="3000"/>
    </set>
    
    旋转动画
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:fillAfter="true">
        <rotate android:fromDegrees="0"
            android:toDegrees="-180"
            android:pivotY="50%"
            android:pivotX="50%"
            android:duration="3000"/>
    </set>
    
    透明度动画
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:fillAfter="true">
        <alpha android:fromAlpha="0.1"
            android:toAlpha="0.9"
            android:duration="3000" />
    </set>
    

    相关文章

      网友评论

          本文标题:动画

          本文链接:https://www.haomeiwen.com/subject/oqgwoftx.html