Android中的属性动画

来源:互联网 发布:sql注入站点 编辑:程序博客网 时间:2024/05/01 10:14

一、视图动画的缺陷
1、视图动画是非交互动画,仅仅改变了显示位置
2、视图动画种类有限,复杂的效果力不从心
3、视图动画调用onDraw来重绘界面,耗费资源
4、视图动画只能针对View实现动画,对非View不能实现。

二、属性动画的特点
1、属性动画真正改变的是对象的属性
2、属性动画是可以交互的
3、属性动画针对View与非View都能实现动画
4、如果属性不存在,还可以自定义属性

三、属性动画对应关系
目标target–>View
时长duration–>duration
开始状态from–>valueFrom
结束状态to–>valueTo
开始时间beginTime–>startOffset
重复次数(repeatCount)–>repeatCount
时间轴(timeline)–>interpolator

四、属性动画代码结构
这里写图片描述
(1)xml实现
在res/animator下定义动画文件

<set xmlns:android="http://schemas.android.com/apk/res/android"     android:ordering="sequentially">    <objectAnimator        android:duration="2000"        android:propertyName="translationY"        android:valueTo="-200f"        android:valueType="floatType"></objectAnimator>    <set android:ordering="together">        <objectAnimator            android:duration="2000"            android:propertyName="scaleX"            android:valueTo="2.0f"            android:valueType="floatType"></objectAnimator>        <objectAnimator            android:duration="2000"            android:propertyName="scaleY"            android:valueTo="2.0f"            android:valueType="floatType"></objectAnimator>    </set></set>

代码中采用AnimatorInflater() loadAnimator()加载
(2)代码实现
采用ObjectAnimator或者ValueAnimator来实现

        ObjectAnimator alpha = ObjectAnimator.ofFloat(love, "alpha", 1.0f, 0.0f);        alpha.setDuration(1000);        alpha.addListener(new Animator.AnimatorListener() {            @Override            public void onAnimationStart(Animator animation) {                Toast.makeText(ObjectAnimationActivity.this, "start", Toast.LENGTH_LONG).show();                ;            }            @Override            public void onAnimationEnd(Animator animation) {            }            @Override            public void onAnimationCancel(Animator animation) {            }            @Override            public void onAnimationRepeat(Animator animation) {            }        });        alpha.start();

(3)没有对应属性
直接添加set函数
包装原有类,添加set函数
采用ValueAnimator实现
示例代码

public class WrapperView {    public ImageView target;    private float scale;    public WrapperView(ImageView target) {        this.target = target;    }    public float getScale() {        return scale;    }    public void setScale(float scale) {        this.scale = scale;        target.setScaleX(scale);        target.setScaleY(scale);    }
    private void addProperty() {        WrapperView view = new WrapperView(love);        ObjectAnimator scale = ObjectAnimator.ofFloat(view, "scale", 1.0f, 2.0f);        scale.setDuration(1000);        scale.start();    }

五、组合动画
这里写图片描述
并行动画示例代码

    private void togetherAnim1() {        ObjectAnimator rotate = ObjectAnimator.ofFloat(love, "rotation", 0f, 360f).setDuration(1000);        ObjectAnimator scaleX = ObjectAnimator.ofFloat(love, "scaleX", 1.0f, 2.0f).setDuration(1000);        ObjectAnimator scaleY = ObjectAnimator.ofFloat(love, "scaleY", 1.0f, 2.0f).setDuration(1000);//        rotate.start();//        scaleX.start();//        scaleY.start();        AnimatorSet set = new AnimatorSet();        set.playTogether(rotate, scaleX, scaleY);        set.setDuration(1000);        set.start();    }

并行动画示例代码(二)

    private void togetherAnim2() {        PropertyValuesHolder rotate = PropertyValuesHolder.ofFloat("rotation", 0f, 360f);        PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f, 2.0f);        PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f, 2.0f);        ObjectAnimator together = ObjectAnimator.ofPropertyValuesHolder(love, rotate, scaleX, scaleY);        together.setDuration(1000);        together.start();    }

并行动画示例代码(三)

    private void togetherAnim3() {        love.animate().rotation(360f).scaleX(2.0f).scaleY(2.0f).setDuration(1000).start();    }

串行动画示例代码

    private void sequenceAnim() {        ObjectAnimator rotate = ObjectAnimator.ofFloat(love, "rotation", 0f, 360f).setDuration(1000);        ObjectAnimator scaleX = ObjectAnimator.ofFloat(love, "scaleX", 1.0f, 2.0f).setDuration(1000);        ObjectAnimator scaleY = ObjectAnimator.ofFloat(love, "scaleY", 1.0f, 2.0f).setDuration(1000);        AnimatorSet set = new AnimatorSet();        set.playSequentially(rotate, scaleX, scaleY);        set.setDuration(1000);        set.start();    }

组合动画示例代码(一)
xml文件

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"     android:ordering="sequentially">    <objectAnimator        android:duration="2000"        android:propertyName="translationY"        android:valueTo="-200f"        android:valueType="floatType"></objectAnimator>    <set android:ordering="together">        <objectAnimator            android:duration="2000"            android:propertyName="scaleX"            android:valueTo="2.0f"            android:valueType="floatType"></objectAnimator>        <objectAnimator            android:duration="2000"            android:propertyName="scaleY"            android:valueTo="2.0f"            android:valueType="floatType"></objectAnimator>    </set></set>

代码

    private void compositeAnimXml(){        Animator animator = AnimatorInflater.loadAnimator(this, R.animator.love_f);        animator.setTarget(love);        animator.start();    }

组合动画示例代码(二)

    private void compositeAnim() {        ObjectAnimator translateY = ObjectAnimator.ofFloat(love, "translationY", -200f).setDuration(1000);        ObjectAnimator scaleX = ObjectAnimator.ofFloat(love, "scaleX", 1.0f, 2.0f).setDuration(1000);        ObjectAnimator scaleY = ObjectAnimator.ofFloat(love, "scaleY", 1.0f, 2.0f).setDuration(1000);        ObjectAnimator rotate = ObjectAnimator.ofFloat(love, "rotation", 0f, -45f).setDuration(1000);        AnimatorSet set = new AnimatorSet();        set.play(scaleX).with(scaleY).with(rotate);        set.play(translateY).after(scaleX);        set.start();    }

注:with,同时执行该动画。before:befoe里的动画后执行。after里的动画先执行。

六、ValueAnimator
(1)ValueAnimator是一个数值发生器
(2)ValueAnimator不做用于任何属性
(3)需要在onAnimationUpdate获取当前时间点发生值。
示例代码
倒计时:

    private void countDown() {        ValueAnimator countDown = ValueAnimator.ofInt(10, 0);        countDown.setDuration(10000);        countDown.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                textView.setText("" + animation.getAnimatedValue());            }        });        countDown.start();    }

七、Evalautor(求值器)
1、返回动画当前时间点的属性值
2、全部继承自TypeEvaluator
3、系统实现了intEvaluator,FloatEvaluator,ArgbEvalutor
4、API21实现了PointFEvalutor
自定义示例代码:
抛物线形状

    private void setCustomEvaluator() {        ValueAnimator animator = new ValueAnimator();        float offsetX = love.getX();        float offsetY = love.getY();        animator.setDuration(2000);        animator.setObjectValues(new PointF(offsetX, offsetY), new PointF(TRANS_X + offsetX, offsetY));        animator.setEvaluator(new TypeEvaluator<PointF>() {            @Override            public PointF evaluate(float fraction, PointF startValue, PointF endValue) {                PointF pointF = new PointF();                float d = fraction * TRANS_X;                pointF.x = startValue.x + d;                pointF.y = startValue.y + (1.0f / 150f) * d * d - 4 * d;                return pointF;            }        });        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                PointF pointF = (PointF) animation.getAnimatedValue();                love.setX(pointF.x);                love.setY(pointF.y);            }        });        animator.start();    }

八、keyFrame(关键帧)
1、keyFrame是一个时间/值对
2、keyFrame之间可以定义不同的Interpolator

    private void keyFrame() {        Keyframe keyframe1 = Keyframe.ofFloat(0f, 0f);        Keyframe keyframe2 = Keyframe.ofFloat(0.5f, 360f);        Keyframe keyframe3 = Keyframe.ofFloat(1.0f, 0f);        PropertyValuesHolder pvh = PropertyValuesHolder.ofKeyframe("rotation", keyframe1, keyframe2, keyframe3);        ObjectAnimator rotate = ObjectAnimator.ofPropertyValuesHolder(love, pvh);        rotate.setDuration(2000);        rotate.start();    }

九、Layout Animations
1、LayoutTransition.APPEARING,对出现的view设置动画
2、LayoutTransition.CHANGE_APPERAING,对其他view设置动画
3、LayoutTransition.DISAPPEARING,对消失的view设置动画
4、LayoutTransition.CHANGE.DISAPPERAING,对其他view设置动画
5、LayoutTransition.CHANGE,对其他view设置动画

    private void findViews() {        root = (LinearLayout) findViewById(R.id.root);        root.setLayoutTransition(getLayoutTransition());    }    private LayoutTransition getLayoutTransition() {        LayoutTransition transition = new LayoutTransition();        transition.setAnimator(LayoutTransition.APPEARING, transition.getAnimator(LayoutTransition.APPEARING));        transition.setAnimator(LayoutTransition.CHANGE_APPEARING, transition.getAnimator(LayoutTransition                .CHANGE_APPEARING));        transition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, transition.getAnimator(LayoutTransition                .CHANGE_DISAPPEARING));        transition.setAnimator(LayoutTransition.DISAPPEARING, transition.getAnimator(LayoutTransition.DISAPPEARING));        transition.setAnimator(LayoutTransition.CHANGING, transition.getAnimator(LayoutTransition.CHANGING));        return transition;    }    private void setViewListener() {        findViewById(R.id.add_view).setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.add_view:                addViews();                break;        }    }    private void addViews() {        final Button button = new Button(this);        button.setText("button=" + i++);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                root.removeView(button);            }        });        root.addView(button);    }

十、页面转场动画
这里写图片描述

    /**     * 只有在start,finish之后才有这个效果     * @param enterAnim     * @param exitAnim     */    @Override    public void overridePendingTransition(int enterAnim, int exitAnim) {        super.overridePendingTransition(enterAnim, exitAnim);    }    @Override    public void finish() {        super.finish();        customExit();    }    private void customExit() {        overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);    }    public static void start(Context context) {        Intent intent = new Intent();        intent.setClass(context, ObjectAnimationActivity.class);        context.startActivity(intent);        ((Activity) context).overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);    }
0 0
原创粉丝点击