zoukankan      html  css  js  c++  java
  • android 属性动画

    一直再追郭霖的博客和imooc上的一些新的视频,最近有讲到属性动画。

    以下内容为博客学习以及imooc上视频资料的学习笔记:

    在3.0之前比较常见的动画为tween动画和frame动画:

    tween动画:就是对场景里的对象不断的进行图像变化来产生动画效果(旋转、平移、放缩和渐变);

    frame动画:即顺序的播放事先做好的图像,与gif图片原理类似,也类似电影效果。

     

    在3.0以后除了支持以上两种动画以外,还增加了一个新的动画:

    property animation----属性动画。

    传统的animation动画,旧的animation只适合显示效果,不适合交互动画

    TranslateAnimation 位移动画

    虽然Imageview可以移动,但是移动后的imageview无法单击,而在旧的位置可以单击,这就是旧的animation的效果。

    ofFloat第一个参数为要操控的控件,第二个为要操作的属性,第三个以及第四个为操作的范围。

    setDuration为操作的时间长度。

    属性动画在移动后的控件位置点击可以toast.

     

    实现控件旋转360度。

     

    多个属性动画的使用:

     PropertyValuesHolder:来控制多个属性的共同作用:

     多个属性动画效果:palyTogether

    按照顺序进行动画播放:playSequentially

     

    动画监听事件:

    另外一种添加事件的监听:

     

    有层次的动画显示风格:

    setStartDelay()设置延迟时间的属性

    插值器:

    setInterpolator(new BounceInterpolator());



    ValueAnimator:

     ObjectAnimator 继承自ValueAnimator,用来产生一定规律的数字,从而控制动画的实现过程。

     AnimatorUpdateListener用来监听数值的变换。

    五秒内button上的内容从1到100:

    通过对数值的处理进行动画效果的处理


    常用属性:

    translationX ,translationY----偏移距离,作为一种增量控制view从布局左上角开始的位置。

    rotation , rotationX ,rotationY,----水平或者竖直方向旋转动画,围绕支点进行2D或者3D旋转。

    scaleX,scaleY----X方向,Y方向的缩放动画,2D缩放。

    pivotX,pivotY--view对象支点位置,围绕该支点进行旋转和缩放变换操作。

    x和Y,--view对象最终位置,起始位置为左上角坐标+偏移距离。

    alpha:透明度,1不透明,0,完全透明。

     

    X,Y,移动到具体那个坐标

    alpha 透明度

     

    常用的方法和类:

    ValueAnimator----数值发生器

    ObjectAnimator----ValueAnimator子类

    AnimatorUpdateListener---动画监听事件

    AnimatorListenerAdapter

    PropertyValuesHolder

    AnimatorSet----动画集合,即可以同时对一个对象应用几个动画,这些动画可以同时播放也可以对不同动画设置不同开始偏移

    TypeEvaluators----根据属性的开始、结束值与TimeInterpolation计算出的因子计算出当前时间的属性值

    Interplators

     

    nterplators图解:

        AccelerateInterpolator          加速,开始时慢中间加速

        DecelerateInterpolator         减速,开始时快然后减速

        AccelerateDecelerateInterolator    先加速后减速,开始结束时慢,中间加速

        AnticipateInterpolator        反向 ,先向相反方向改变一段再加速播放

        AnticipateOvershootInterpolator    反向加回弹,先向相反方向改变,再加速播放,会超出目的值然后缓慢移动   至目的值

        BounceInterpolator         跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100

        CycleIinterpolator         循环,动画循环一定次数,值的改变为一正弦函数:Math.sin(2 * mCycles * Math.PI * input)

        LinearInterpolator         线性,线性均匀改变

        OvershottInterpolator        回弹,最后超出目的值然后缓慢改变到目的值

        TimeInterpolator           一个接口,允许你自定义interpolator,以上几个都是实现了这个接口

    来源: <http://www.cnblogs.com/angeldevil/archive/2011/12/02/2271096.html>

    相关进阶资料:

    http://www.cnblogs.com/angeldevil/archive/2011/12/02/2271096.html

    AnimatorSeth和AnimatorListener:http://blog.csdn.net/new_abc/article/details/40143091

    使用ObjectAnimator设置动画http://blog.csdn.net/new_abc/article/details/40106569

    使用ValueAnimator设置动画http://blog.csdn.net/new_abc/article/details/40072499


     

    在xml中使用属性动画,下面几篇文章讲的非常之详细

    《Animation 动画详解(一)——alpha、scale、translate、rotate、set的xml属性及用法》

    《Animation动画详解(二)——Interpolator插值器》

    《Animation动画详解(三)—— 代码生成alpha、scale、translate、rotate、set及插值器动画》

    加载布局里面的动画:

    首先anim文件夹下面定义动画,比如:

     R.anim.rotate_one.xml

    <?xml version="1.0" encoding="utf-8"?>
    <rotate xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="500"
        android:fillAfter="true"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="-180" >
    
    </rotate>
    BasicXMLAnimationActivity.java文件中调用
    package com.example.viewanimation.basic;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.animation.Animation;
    import android.view.animation.AnimationUtils;
    
    import com.example.helloanimation.R;
    
    public class BasicXMLAnimationActivity extends Activity {
    
        private Animation mTurnupAnimation;
        private Animation mTurndownAnimation;
        private Animation mTranslateAnimationOne;
        private Animation mTranslateAnimationTwo;
        private Animation mAlphaAnimationSet;
        private Animation mScaleAnimation;
    
        private View mStartButton = null;
        private View mTargetView = null;
        private int mStateId = 0;
        private int mStateCount = 6;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.basic_view_animation);
            initAnimations();
            mStartButton = findViewById(R.id.startButton);
            mStartButton.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
    
                    playAnimations();
                }
            });
            mTargetView = findViewById(R.id.target);
        }
    
        private void initAnimations() {
            mTurnupAnimation = AnimationUtils
                    .loadAnimation(this, R.anim.rotate_one);
    
            mTurndownAnimation = AnimationUtils.loadAnimation(this,
                    R.anim.rotate_two);
    
            mTranslateAnimationOne = AnimationUtils.loadAnimation(this,
                    R.anim.translate_one);
    
            mTranslateAnimationTwo = AnimationUtils.loadAnimation(this,
                    R.anim.translate_two);
    
            mAlphaAnimationSet = AnimationUtils.loadAnimation(this,
                    R.anim.alpha_ani_set);
    
            mScaleAnimation = AnimationUtils.loadAnimation(this, R.anim.scale_one);
    
        }
    
        private void playAnimations() {
            switch (mStateId) {
            case 0:
                mTargetView.startAnimation(mTurndownAnimation);
                break;
            case 1:
                mTargetView.startAnimation(mTurnupAnimation);
                break;
            case 2:
                mTargetView.startAnimation(mTranslateAnimationOne);
                break;
            case 3:
                mTargetView.startAnimation(mTranslateAnimationTwo);
                break;
            case 4:
                mTargetView.startAnimation(mAlphaAnimationSet);
                break;
            case 5:
                mTargetView.startAnimation(mScaleAnimation);
                break;
    
            default:
                break;
            }
    
            mStateId = (++mStateId) % mStateCount;
    
        }
    }

     


     

    android 布局动画

    LayoutTransition 对ViewGroup中的View改变进行动画显示

    <LinearLayout android:id="@+id/container"
        android:animateLayoutChanges="true"
        ...
    />

    代码中使用:

    private ViewGroup mContainerView;
    ...
    private void addItem() {
        View newView;
        ...
        mContainerView.addView(newView, 0);
    }

    生成transition对象:

     mTransitioner = new LayoutTransition();
     container.setLayoutTransition(mTransitioner);

    为transition添加动画:

     ObjectAnimator animIn = ObjectAnimator.ofFloat(null, "rotationY", 90f,
                    0f).setDuration(
                    mTransitioner.getDuration(LayoutTransition.APPEARING));
            mTransitioner.setAnimator(LayoutTransition.APPEARING, animIn);
            animIn.addListener(new AnimatorListenerAdapter() {
                public void onAnimationEnd(Animator anim) {
                    View view = (View) ((ObjectAnimator) anim).getTarget();
                    view.setRotationY(0f);
                }
            });

     属性动画之插值器

    属性动画之插值器

    定义:定义动画变换效率,控制目标变量的变化值进行对应的变化,同样,一个动画变换起始值,在不同的插值器作用下,每个单位时间内所达到的变量值不同。

    下面举例子说明:

    动画是放大缩小的动画,通过scale动画来控制,首先在anim里面定义动画的xml文件:

    scaleanim_decelerate.xml

    <?xml version="1.0" encoding="utf-8"?>
    <scale xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="700"
        android:fillAfter="true"
        android:fromXScale="0.0"
        android:fromYScale="0.0"
        android:interpolator="@android:anim/decelerate_interpolator"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1.4"
        android:toYScale="1.4" />

     

    插值器使用decelerate_interpolator插值器,( 减速,开始时快然后减速)也就是说如下方式的动画:

    java代码里面调用:
    1,首先获取动画的对象;
    Animation decelerateAnim = AnimationUtils.loadAnimation(this, R.anim.scaleanim_decelerate);

     

    2,在合适的地方进行调用:
    tv.startAnimation(decelerateAnim);  

    RotateAnimation、ScaleAnimation、TranslateAnimation都存在一对pivotXType,pivotYType参数,
    它们是用来指定点的参照类型,使用int类型以静态常量的形式定义在Animation中。

    ABSOLUTE:以绝对坐标为参照。
    RELATIVE_TO_PARENT:以父容器为参照。
    RELATIVE_TO_SELF:以当前容器为参照。

     

    在使用XML定义动画资源的时候,没有关于pivotXType、pivotYType两个属性,其实它们结合到了设定点的坐标中中,以 pivotXValue、pivotYValue两个属性替代,其中如果需要设定为父容器为参照,需要在属性值后面加"p"即可。   
     
    插值器xml文件里面属性意义:
        浮点型值:
          fromXScale 属性为动画起始时 X坐标上的伸缩尺寸    
          toXScale   属性为动画结束时 X坐标上的伸缩尺寸     
          fromYScale 属性为动画起始时Y坐标上的伸缩尺寸    
          toYScale   属性为动画结束时Y坐标上的伸缩尺寸    
          说明:
          以上四种属性值    
          0.0表示收缩到没有 
          1.0表示正常无伸缩     
          值小于1.0表示收缩  
          值大于1.0表示放大 
          pivotX     属性为动画相对于物件的X坐标的开始位置(坐标原点X点坐标)
          pivotY     属性为动画相对于物件的Y坐标的开始位置(坐标原点Y点坐标)
          说明:
          以上两个属性值 从0%-100%中取值
          50%为物件的X或Y方向坐标上的中点位置
          长整型值:
          duration  属性为动画持续时间
          说明:   时间以毫秒为单位
     
          布尔型值:
          fillAfter 属性 当设置为true ,该动画转化在动画结束后被应用  
     

    自定义动画:

    自定义动画首先要继承android.view.animation.Animation,
    重写applyTransformation(float interpolatedTime, Transformation t)函数来实现自定义动画效果;
    重写initialize (int width, int height, int parentWidth, int parentHeight)函数,这是一个回调函数告诉Animation目标View的大小参数,在这里可以初始化一些相关的参数。
     
    首先:
    applyTransformation(float interpolatedTime, Transformation t)
    interpolatedTime:插值器时间因子,由动画当前完成的百分比和当前时间对应的插值所计算出来的,取值范围0--1.0.
    Transformation :矩阵封装类。
    下面是个例子,效果是从小往大,左右旋转的效果的动画
    import android.graphics.Camera;
    import android.graphics.Matrix;
    import android.view.animation.Animation;
    import android.view.animation.LinearInterpolator;
    import android.view.animation.Transformation;
    
    class ViewAnimation extends Animation {
        int mCenterX;
        int mCenterY;
        Camera camera = new Camera();
    
        public ViewAnimation() {
        }
    
        //初始化操作
        @Override
        public void initialize(int width, int height, int parentWidth,
            int parentHeight) {
            super.initialize(width, height, parentWidth, parentHeight);
            
            mCenterX = width / 2;
    
            mCenterY = height / 2;
            //设置时间长短
            setDuration(2500);
            //动画结束后保持状态
            setFillAfter(true);
            //设置插值器 ,线性均匀改变
            setInterpolator(new LinearInterpolator());
        }
    
        //定义动画的进行过程
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            final Matrix matrix = t.getMatrix();
    
            camera.save();
            //设置移动
            camera.translate(0.0f, 0.0f, (1300 - (1300.0f * interpolatedTime)));
            //设置旋转角度
            camera.rotateY(360 * interpolatedTime);
            //将变换作用于matrik上
            camera.getMatrix(matrix);
            //矩阵作用前的偏移量
            matrix.preTranslate(-mCenterX, -mCenterY);
    
            matrix.postTranslate(mCenterX, mCenterY);
    
            camera.restore();
        }
    }

    使用:

    初始化animation:

    ViewAnimation viewAnimation = new ViewAnimation();

    触发事件中进行调用:

    tv.startAnimation(viewAnimation);
    Camera常用的方法:

    rotateX(float degree) 绕着x轴旋转degree个度数

    rotateY(float degree) 绕着y轴旋转degree个度数

    rotateZ(float degree) 绕着z轴旋转degree个度数

    translate(float x,float y,float z) 平移一段距离

    save()保存原状态

    restore() 操作完之后,恢复到原状态。

     
     
     
  • 相关阅读:
    [leetcode-135-Candy]
    [leetcode-151-Reverse Words in a String]
    [leetcode-139-Word Break]
    [leetcode-129-Sum Root to Leaf Numbers]
    [leetcode-143-Reorder List]
    [leetcode-141-Linked List Cycle]
    oracle 环境变量(中文显示乱码)
    Oracle 自增长id
    Spring.net 事件的注入
    Spirng.net 替换任意方法
  • 原文地址:https://www.cnblogs.com/androidsuperman/p/4474604.html
Copyright © 2011-2022 走看看