android基础(动画)

来源:互联网 发布:linux新建用户并授权 编辑:程序博客网 时间:2024/05/17 02:39

安卓动画主要有三类:逐帧动画(Drawable Animation、Frame Animation)、补间动画(View Animaiton、Tweened Animation)、属性动画(Property Animation),其中,View Animation只能修改View组件的部分属性、动画效果是绘制出来的,组件并没有真正改变,而Property Animation可以修改任何对象的任何属性,组件的状态也会跟着改变

Drawable Animation

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"

    android:oneshot="false">

    <item android:duration="100">

        <layer-list>

            <item android:drawable="@drawable/login_loading_00" />

            <item android:drawable="@drawable/login_loading_10" />

        </layer-list>

    </item>

    <item android:duration="100">

        <layer-list>

            <item android:drawable="@drawable/login_loading_01" />

            <item android:drawable="@drawable/login_loading_11" />

        </layer-list>

    </item>

</animation-list>

其中,android:oneshot=true”表示该动画只播放一次,等于false时则循环播放。<item/>标签定义各个帧显示的图片显示顺序依照<item/>定义顺序,<layer-list/>内包含的图片将层叠起来,在同一帧中一起显示

private AnimationDrawable loadingAnimation;

loadingAnimation.stop();

loadingAnimation.start();

View Animation

View Animation效果由四个因素决定:1)初始状态;2)结束状态;3)持续时间;4Interpolator

四大类:AlphaAnimation,RotateAnimation,ScaleAnimation,TranslateAnimation

代码实现View Animation

TranslateAnimation tAnim = new TranslateAnimation(0, 400, 0, 0);

RotateAnimation rAnima = new RotateAnimation(0, 70);

ScaleAnimation sAnima = new ScaleAnimation(0, 5, 0, 5);

AlphaAnimation aAnima = new AlphaAnimation(1.0f, 0.0f);

 

tAnim.setDuration(2000);

tAnim.setInterpolator(new AccelerateDecelerateInterpolator());

translation.startAnimation(tAnim);

XML文件实现View Animation

<set xmlns:android="http://schemas.android.com/apk/res/android"

    android:shareInterpolator="false">

    <scale

        android:interpolator="@android:anim/accelerate_decelerate_interpolator"

        android:fromXScale="1.0"

        android:toXScale="1.4"

        android:fromYScale="1.0"

        android:toYScale="0.6"

        android:pivotX="50%"

        android:pivotY="50%"

        android:fillAfter="false"

        android:duration="1000" />

    <set

        android:interpolator="@android:anim/accelerate_interpolator"

        android:startOffset="1000">

        <scale …  />

        <rotate

            android:fromDegrees="0"

            android:toDegrees="60"

            android:pivotX="50%"

            android:pivotY="50%"

            android:duration="400" />

    </set>

</set>

android:fillAfter:设置fillAftertrue,动画将保持结束的状态

Animation anim = AnimationUtils.loadAnimation(AnimaXmlActivity.this, R.anim.myanim);

img.startAnimation(anim);

Property Animation:

通过动画的方式改变对象的属性,动画的执行类: ObjectAnimatorValueAnimator

AnimatorSet用于控制一组动画的执行顺序

AnimatorInflater用于加载属性动画的XML文件

TypeEvaluator类型估值,用于设置动画操作属性的值

PropertyValuesHolder实现一个动画更改多个效果

TimeInterpolator时间插值

ObjectAnimator

ObjectAnimator.ofFloat(view, "rotationX", 0.0F, 360.0F).setDuration(500).start();

1ObjectAnimator提供了ofIntofFloatofObject,这几个方法都是设置动画作用的元素、作用的属性、动画开始、结束的属性值,当只设置一个属性值的时候,会认为当然对象的属性值为开始(getPropName反射获取),设置的值为终点,如果设置两个,则一个为开始、一个为结束。动画更新的过程中,会不断调用setPropName更新元素的属性,所有使用ObjectAnimator更新的属性,必须得有getter(设置属性值的时候)和setter方法。

2、如果操作的属性方法内部没有调用view的重绘,比如setRotationX,则需要手动调用

anim.addUpdateListener(new AnimatorUpdateListener() {

@Override

       public void onAnimationUpdate(ValueAnimator animation) {

           view.postInvalidate();

           view.invalidate();

        }

});

3.通过ObjectAnimatorView既缩小、又淡出(属性scaleX,scaleY,alpha

public void rotateAnimRun(final View view) {

    ObjectAnimator anim = ObjectAnimator.ofFloat(view, "zhy", 1.0F,  0.0F).setDuration(500);

    anim.start();

    anim.addUpdateListener(new AnimatorUpdateListener() {

        @Override

        public void onAnimationUpdate(ValueAnimator animation) {

            float cVal = (Float) animation.getAnimatedValue();

            view.setAlpha(cVal);

            view.setScaleX(cVal);

            view.setScaleY(cVal);

        }

    });

}

4.使用propertyValuesHolder实现一个动画更改多个效果:

    public void propertyValuesHolder(View view) {

        PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f, 0f, 1f);

        PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f);

        PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f, 0, 1f);

        ObjectAnimator.ofPropertyValuesHolder

                   (view, pvhX, pvhY,pvhZ).setDuration(1000).start();

    }

ValueAnimator

ObjectAnimator的区别之处:ValueAnimator本身并没有在属性上做操作,因此,不需要操作对象的属性一定要有gettersetter方法,你可以自己根据当前动画的计算值,来操作任何属性

    public void verticalRun( View view) {

        ValueAnimator animator =

                ValueAnimator.ofFloat(0, mScreenHeight - mBlueBall.getHeight());

        animator.setDuration(1000).start();

        animator.setInterpolator(value)

        animator.addUpdateListener(new AnimatorUpdateListener() {

            @Override

            public void onAnimationUpdate(ValueAnimator animation) {

                mBlueBall.setTranslationY((Float) animation.getAnimatedValue());

            }

        });

    }

实现抛物线的效果,水平方向100px/s,垂直方向加速度200px/s*s

    public void paowuxian(View view) {

        ValueAnimator valueAnimator = new ValueAnimator();

        valueAnimator.setObjectValues(new PointF(0, 0));

        valueAnimator.setDuration(3000);

        valueAnimator.setInterpolator(new LinearInterpolator());

        valueAnimator.setEvaluator(new TypeEvaluator<PointF>() {

            // fraction = t / duration

            @Override  

            public PointF evaluate(float fraction, PointF startValue, PointF endValue) {

                PointF point = new PointF();

                point.x = 200 * fraction * 3;

                point.y = 0.5f * 200 * (fraction * 3) * (fraction * 3);

                return point;

            }

        });

        valueAnimator.start();

        valueAnimator.addUpdateListener(new AnimatorUpdateListener() {

            @Override  

            public void onAnimationUpdate(ValueAnimator animation) {

                PointF point = (PointF) animation.getAnimatedValue();

                mBlueBall.setX(point.x);

                mBlueBall.setY(point.y);

            }

        });

    }

监听事件:对于动画,一般都是一些辅助效果,比如我要删除个元素,我可能希望是个淡出的效果,但是最终还是要删掉,并不是你透明度没有了,还占着位置,所以我们需要知道动画如何结束

    public void fadeOut(View view) {

        ObjectAnimator anim = ObjectAnimator.ofFloat(mBlueBall, "alpha", 0.5f);

        anim.addListener(new AnimatorListener() {

            @Override

            public void onAnimationStart(Animator animation) { }

            @Override

            public void onAnimationRepeat(Animator animation) { }

            @Override

            public void onAnimationEnd(Animator animation) { }

            @Override

            public void onAnimationCancel(Animator animation) { }

        });

        anim.start();

    }

AnimatorListenerAdapter:有时候,我只要监听某个状态,这么长的代码我不能接受

anim.addListener(new AnimatorListenerAdapter() {

    @Override

    public void onAnimationEnd(Animator animation) { }

});

AnimatorSet

    public void togetherRun(View view) {

        ObjectAnimator anim1 = ObjectAnimator.ofFloat(mBlueBall, "scaleX", 1.0f, 2f);

        ObjectAnimator anim2 = ObjectAnimator.ofFloat(mBlueBall, "scaleY", 1.0f, 2f);

        ObjectAnimator anim3 = ObjectAnimator.ofFloat(mBlueBall, "x",  cx ,  0f);

       ObjectAnimator anim4 = ObjectAnimator.ofFloat(mBlueBall, "x", cx);

//anim1anim2anim3anim4接着执行

        AnimatorSet animSet = new AnimatorSet();

        animSet.setDuration(2000);

        animSet.setInterpolator(new LinearInterpolator());

        animSet.playTogether(anim1, anim2);

        animSet.start();

        //anim1anim2anim3同时执行,anim4接着执行

        AnimatorSet animSet = new AnimatorSet();

        animSet.play(anim1).with(anim2);

        animSet.play(anim2).with(anim3);

        animSet.play(anim4).after(anim3);

        animSet.setDuration(1000);

        animSet.start();

    }

xml文件实现Property Animation

View Animator Drawable Animatoranim文件夹下创建动画。Property Animatoranimator文件夹下创建动画

<set xmlns:android="http://schemas.android.com/apk/res/android"

    android:ordering="together">

    <objectAnimator

        android:duration="1000"

        android:propertyName="scaleX"

        android:valueFrom="1.0"

        android:valueTo="0.5">

    </objectAnimator>

    <objectAnimator

        android:duration="1000"

        android:propertyName="scaleY"

        android:valueFrom="1.0"

        android:valueTo="0.5">

    </objectAnimator>

</set>

 

Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scale);

mMv.setPivotX(0);

mMv.setPivotY(0);

mMv.invalidate();

anim.setTarget(mMv);

anim.start();

orderring表示播放顺序,还有另一个值:sequentially(表示一个接一个执行),缩放、反转等默认是中心缩放,和对称轴为反转线,本例子以左上角为中心点

布局动画(Layout Animations)

LayoutTransition transition = new LayoutTransition();

transition.setAnimator(LayoutTransition.CHANGE_APPEARING,

            transition.getAnimator(LayoutTransition.CHANGE_APPEARING));

transition.setAnimator(LayoutTransition.APPEARING,  null);

transition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING,  null);

mGridLayout.setLayoutTransition(transition);

过渡动画类型:

LayoutTransition.APPEARING:ViewViewGroup中出现时,对此View设置动画

LayoutTransition.CHANGE_APPEARING:当一个ViewViewGroup中出现时,对此View对其他View位置造成影响,对其他View设置的动画

LayoutTransition.DISAPPEARING:当一个ViewViewGroup中消失时,对此View设置的动画

LayoutTransition.CHANGE_DISAPPEARING:当一个ViewViewGroup中消失时,对此View对其他View位置造成影响,对其他View设置的动画

 

Viewanim方法:SDK11的时候,给View添加了animate方法,更加方便的实现动画效果

public void viewAnim(View view) {

    // need API 12

    mBlueBall.animate().alpha(0).y(mScreenHeight / 2).setDuration(1000)  

    // need API 16

    .withStartAction(new Runnable() {

        public void run() {   Log.e(TAG, "START");  }

    }).withEndAction(new Runnable() {

        @Override

        public void run() {

            runOnUiThread(new Runnable() {

                @Override

                public void run() {

                    mBlueBall.setY(0);

                    mBlueBall.setAlpha(1.0f);

                }

            });

        }

}).start();

}

 

runOnUiThread:

首先判断是否是UI线程,不是的话就post,如果是的话就正常运行该线程,只要经过主线程中的Handler.post或者postDelayed处理线程runnable则都可以将其转为UI主线程.再说Handler的机制就是来处理线程与UI通讯的

0 0
原创粉丝点击