码迷,mamicode.com
首页 > 其他好文 > 详细

属性动画 LayoutTransition AnimatorInflater Keyframe 新特性

时间:2016-04-20 01:46:20      阅读:276      评论:0      收藏:0      [点我收藏+]

标签:


LayoutTransition设置动画

使用LayoutTransition可为布局的容器设置动画,当容器中的视图层次发生变化时产生相应的过渡的动画效果

过渡的类型一共有四种:
  • LayoutTransition.APPEARING 当一个View在ViewGroup中出现时,对此View设置的动画
  • LayoutTransition.CHANGE_APPEARING 当一个View在ViewGroup中出现时,对此View对其他View位置造成影响,对其他View设置的动画
  • LayoutTransition.DISAPPEARING  当一个View在ViewGroup中消失时,对此View设置的动画
  • LayoutTransition.CHANGE_DISAPPEARING 当一个View在ViewGroup中消失时,对此View对其他View位置造成影响,对其他View设置的动画
AnimateLayoutChanges动画:
        ViewGroup的xml属性中有一个animateLayoutChanges属性,设置该属性为true,可以添加ViewGroup增加view的过渡效果:
示例:
        mTransition = new LayoutTransition();
        mTransition.setAnimator(LayoutTransition.APPEARING, ObjectAnimator.ofFloat(this"scaleX", 0, 1));
        mTransition.setAnimator(LayoutTransition.CHANGE_APPEARINGmTransition.getAnimator(LayoutTransition.CHANGE_APPEARING));
        mTransition.setAnimator(LayoutTransition.DISAPPEARINGmTransition.getAnimator(LayoutTransition.DISAPPEARING));
        mTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARINGmTransition.getAnimator(LayoutTransition.CHANGE_DISAPPEARING));
        gl_container.setLayoutTransition(mTransition);  

XML中设置属性动画

set标签的orderring属性设置为together表示同时播放,sequentially表示一个接一个播放

缩放、反转等都有中心点或者轴,默认为中心缩放,中间对称线为反转线,通过setPivotX(),setPivotY()可改变中心的位置
        Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scale);
        mChangeAppear.setPivotX(0);//设置缩放、反转时的中心点或者轴
        mChangeAppear.setPivotY(0);
        mChangeAppear.invalidate();//设置后要显示的调用invalidate
        anim.setTarget(mChangeAppear);
        anim.start();  

KeyFrame动画

KeyFrame是一个【时间/值】对,通过它可以定义一个在特定时间的特定状态,即【关键帧】,而且在两个keyFrame之间可以定义不同的【Interpolator】,就好像多个动画的拼接,第一个动画的结束点是第二个动画的开始点。

KeyFrame是抽象类,要通过ofInt(),ofFloat(),ofObject()获得适当的KeyFrame,然后通过PropertyValuesHolder.ofKeyframe获得PropertyValuesHolder对象,然后通过ObjectAnimator.ofPropertyValuesHolder获得一个Animator对象。

      Keyframe kf0 = Keyframe.ofInt(0, 300);
        Keyframe kf1 = Keyframe.ofInt(0.2f, 800);//动画开始1/5时 Width=600
        Keyframe kf2 = Keyframe.ofInt(0.4f, 300);
        PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("width", kf0, kf1, kf2);
        ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(mDisAppear, pvhRotation);
        rotationAnim.setDuration(5000).start();


View的animate动画-新API

SDK11的时候,给View添加了animate方法,可以使用一行代码非常方便的实现动画效果。

此后在SDK12,SDK16又分别添加了withStartAction和withEndAction用于在动画前、动画后执行一些操作,当然也可以.setListener(listener)完成此操作。

如:

view.animate().alpha(0.2F).y(1000).setDuration(2000).withStartAction(new Runnable() {
            @Override
            public void run() {
                mChangeDisAppear.setX(200);
            }
        }).withEndAction(new Runnable() {
            @Override
            public void run() {
                mChangeDisAppear.setRotation(-30);//是相对初始值转了-30°
            }
        }).start();


我们也可以使用PropertyValueHolder实现上面的变化,效果与上面一样

        PropertyValuesHolder pvhA = PropertyValuesHolder.ofFloat("alpha", 1f, 0f);
        PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 0, 200);
        ObjectAnimator.ofPropertyValuesHolder(iv, pvhA, pvhY).setDuration(1000).start();

注意,这种动画不再是View动画了,而是属性动画的一种,因为改变了控件的实际属性。


代码
public class MainActivity extends Activity implements OnCheckedChangeListener {
    private GridLayout gl_container;//放置按钮的父布局
    private int mVal;//按钮的编号
    private LayoutTransition mTransition;//布局动画,当容器中的视图发生变化时存在过渡的动画效果
    private CheckBox mAppearmChangeAppearmDisAppearmChangeDisAppear;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        gl_container = (GridLayout) findViewById(R.id.gl_container);
        mAppear = (CheckBox) findViewById(R.id.id_appear);
        mChangeAppear = (CheckBox) findViewById(R.id.id_change_appear);
        mDisAppear = (CheckBox) findViewById(R.id.id_disappear);
        mChangeDisAppear = (CheckBox) findViewById(R.id.id_change_disappear);
        //CheckBox选中状态改变监听,默认全部选中,即动画全部开启
        mAppear.setOnCheckedChangeListener(this);
        mChangeAppear.setOnCheckedChangeListener(this);
        mDisAppear.setOnCheckedChangeListener(this);
        mChangeDisAppear.setOnCheckedChangeListener(this);
        mTransition = new LayoutTransition();
        gl_container.setLayoutTransition(mTransition);
    }
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        mTransition = new LayoutTransition();
        //当一个View在ViewGroup中【出现】时,对此【View】设置的动画
        mTransition.setAnimator(LayoutTransition.APPEARING//=2,下面使用的是自定义的动画
                (mAppear.isChecked() ? ObjectAnimator.ofFloat(this"scaleX", 0, 1) : null));
        //当一个View在ViewGroup中【出现】时,对此View对其他View位置造成影响,对【其他View】设置的动画
        mTransition.setAnimator(LayoutTransition.CHANGE_APPEARING,//=0,下面都是使用默认的动画
                (mChangeAppear.isChecked() ? mTransition.getAnimator(LayoutTransition.CHANGE_APPEARING) : null));
        //当一个View在ViewGroup中【消失】时,对此【View】设置的动画
        mTransition.setAnimator(LayoutTransition.DISAPPEARING//=3
                (mDisAppear.isChecked() ? mTransition.getAnimator(LayoutTransition.DISAPPEARING) : null));
        //当一个View在ViewGroup中【消失】时,对此View对其他View位置造成影响,对【其他View】设置的动画
        mTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING,//=1
                (mChangeDisAppear.isChecked() ? mTransition.getAnimator(LayoutTransition.CHANGE_DISAPPEARING) : null));
        gl_container.setLayoutTransition(mTransition);
    }
    // 向GridLayout中添加按钮
    public void addBtn(View view) {
        final Button button = new Button(this);
        button.setText("" + (++mVal));
        gl_container.addView(button, gl_container.getChildCount());//放置在最后那个位置
        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                gl_container.removeView(button);
            }
        });
    }

    //XML属性动画1,单个动画
    public void xmlAnim1(View view) {
        // 加载动画
        Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scalex);
        mAppear.setPivotX(0);//设置缩放、反转时的中心点或者轴
        mAppear.invalidate();//设置后要显示的调用invalidate才能生效
        anim.setTarget(mAppear);
        anim.start();
    }
    //XML属性动画2,多动画
    public void xmlAnim2(View view) {
        Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scale);
        mChangeAppear.setPivotX(0);//设置缩放、反转时的中心点或者轴
        mChangeAppear.setPivotY(0);
        mChangeAppear.invalidate();//设置后要显示的调用invalidate
        anim.setTarget(mChangeAppear);
        anim.start();
    }

    //Keyframe动画
    public void keyframe(View view) {
        Keyframe kf0 = Keyframe.ofInt(0, 300);
        Keyframe kf1 = Keyframe.ofInt(0.2f, 800);//动画开始1/5时 Width=600
        Keyframe kf2 = Keyframe.ofInt(0.4f, 300);
        Keyframe kf3 = Keyframe.ofInt(0.6f, 100);
        Keyframe kf4 = Keyframe.ofInt(0.8f, 50);
        Keyframe kf5 = Keyframe.ofInt(1f, 500);
        PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("width", kf0, kf1, kf2, kf3, kf4, kf5);
        ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(mDisAppear, pvhRotation);
        rotationAnim.setDuration(5000).start();
    }

    //新版本View动画
    public void viewAnimForNew(View view) {
        mChangeDisAppear.animate().alpha(0.2F).y(1000).setDuration(2000).withStartAction(new Runnable() {
            @Override
            public void run() {
                mChangeDisAppear.setX(200);
                mChangeDisAppear.setRotation(180);
            }
        }).withEndAction(new Runnable() {
            @Override
            public void run() {
                mChangeDisAppear.setX(200);
                mChangeDisAppear.setY(300);
                mChangeDisAppear.setAlpha(1.0f);
                mChangeDisAppear.setRotation(-30);//是相对初始值转了-30°
            }
        }).start();
    }
}

XML动画

scalex.xml

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:propertyName="scaleX"
    android:repeatCount="1"
    android:repeatMode="reverse"
    android:startOffset="1000"
    android:valueFrom="2.5"
    android:valueTo="10"
    android:valueType="floatType" >
</objectAnimator>

scale.xml

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="sequentially" >
    <objectAnimator
        android:duration="500"
        android:propertyName="rotationX"
        android:startOffset="0"
        android:valueFrom="0"
        android:valueTo="360" >
    </objectAnimator>
    <objectAnimator
        android:duration="200"
        android:propertyName="scaleY"
        android:startOffset="500"
        android:valueFrom="1"
        android:valueTo="1.7" >
    </objectAnimator>
    <objectAnimator
        android:duration="200"
        android:propertyName="scaleX"
        android:startOffset="700"
        android:valueFrom="1"
        android:valueTo="1.5" >
        <objectAnimator
            android:duration="100"
            android:propertyName="alpha"
            android:startOffset="900"
            android:valueFrom="1"
            android:valueTo="0.2" >
        </objectAnimator>
    </objectAnimator>
</set>

布局

技术分享 技术分享

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/id_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="xmlAnim1"
            android:text="XML属性动画1" />
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="xmlAnim2"
            android:text="XML属性动画2" />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="keyframe"
            android:text="Keyframe动画" />
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="viewAnimForNew"
            android:text="view的animate动画" />
    </LinearLayout>
    <CheckBox
        android:id="@+id/id_appear"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#200f"
        android:checked="true"
        android:text="APPEARING" />
    <CheckBox
        android:id="@+id/id_change_appear"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#2ff0"
        android:checked="true"
        android:text="CHANGE_APPEARING" />
    <CheckBox
        android:id="@+id/id_disappear"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#20f0"
        android:checked="true"
        android:text="DISAPPEARING" />
    <CheckBox
        android:id="@+id/id_change_disappear"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#2f00"
        android:checked="true"
        android:text="CHANGE_DISAPPEARING " />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:onClick="addBtn"
        android:text="点击添加按钮,点击添加的按钮删除按钮" />
    <GridLayout
        android:id="@+id/gl_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:animateLayoutChanges="false"
        android:background="#40f0"
        android:columnCount="5" />
</LinearLayout>





附件列表

     

    属性动画 LayoutTransition AnimatorInflater Keyframe 新特性

    标签:

    原文地址:http://www.cnblogs.com/baiqiantao/p/5410853.html

    (0)
    (0)
       
    举报
    评论 一句话评论(0
    登录后才能评论!
    © 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
    迷上了代码!