android动画学习(6)-动画补充

一.属性动画补充

1.属性动画补充-为不具有get/set方法的属性提供修改方法

在前一篇文章讲到ObjectAnimator对View的属性进行动画,该属性需要在view有set/get方法,但是对不具有get/set方法的属性该如何进行动画:

Google在应用层为我们提供了2种解决方法,一种是通过自己写一个包装类,来为该属性提供get/set方法,还有一种是通过ValueAnimator来实现,ValueAnimator的方法我们在下面会具体讲解,这里讲解下如何使用自定义的包装类来给属性提供get/set方法。

包装类

private static class WrapperView {
            private View mTarget;
 
            public WrapperView(View target) {
                mTarget = target;
            }
 
            public int getWidth() {
                return mTarget.getLayoutParams().width;
            }
 
            public void setWidth(int width) {
                mTarget.getLayoutParams().width = width;
                mTarget.requestLayout();
            }
        }

使用方法

WrapperView wrapper = new WrapperView (mButton);
ObjectAnimator.ofInt(wrapper, "width", 500).setDuration(5000).start();

这样就间接给他加上了get/set方法,从而可以修改其属性实现动画效果。

2.多动画效果的另一种实现方法——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();
    }

3.KeyFrame

keyFrame是一个 时间/值 对,通过它可以定义一个在特定时间的特定状态,即关键帧,而且在两个keyFrame之间可以定义不同的Interpolator,就好像多个动画的拼接,第一个动画的结束点是第二个动画的开始点。KeyFrame是抽象类,要通过ofInt(),ofFloat(),ofObject()获得适当的KeyFrame,然后通过PropertyValuesHolder.ofKeyframe获得PropertyValuesHolder对象,
有如下案例:

Keyframe kf0 = Keyframe.ofInt(0, 400);
Keyframe kf1 = Keyframe.ofInt(0.25f, 200);
Keyframe kf2 = Keyframe.ofInt(0.5f, 400);
Keyframe kf4 = Keyframe.ofInt(0.75f, 100);
Keyframe kf3 = Keyframe.ofInt(1f, 500);
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("width", kf0, kf1, kf2, kf4, kf3);
ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(btn2, pvhRotation);
rotationAnim.setDuration(2000);

分析:上述代码的意思为:设置btn对象的width属性值使其:
  开始时 Width=400,动画开始1/4时 Width=200,动画开始1/2时 Width=400,动画开始3/4时 Width=100,动画结束时 Width=500
  第一个参数为时间百分比,第二个参数是在第一个参数的时间时的属性值。
  定义了一些Keyframe后,通过PropertyValuesHolder类的方法ofKeyframe一个PropertyValuesHolder对象,然后通过ObjectAnimator.ofPropertyValuesHolder获得一个Animator对象。
上述代码也可替换为(上述代码时间值是线性,变化均匀):

ObjectAnimator oa=ObjectAnimator.ofInt(btn2, "width", 400,200,400,100,500);
oa.setDuration(2000);
oa.start();

4.View的animate方法

3.0后android对View也提供了直接作用的动画API:

view.animate().alpha(0).y(100).setDuration(1000)
                .withStartAction(new Runnable() {
                    @Override
                    public void run() {
                    }
                }).withEndAction(new Runnable() {
                    @Override
                    public void run() {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                            }
                        });
                    }
                }).start();

二.布局动画 - ViewGroup在布局时产生的动画效果

1.LayoutTransition

通过LayoutTransition来实现容器在添加子view的时候的动画过渡效果:
过渡的类型一共有四种:

  1. 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设置的动画
  • LayoutTransition.CHANGE 不是由于View出现或消失造成对其他View位置造成影响,然后对其他View设置的动画。
    注意动画到底设置在谁身上,此View还是其他View。

2.AnimateLayoutChanges动画

ViewGroup的xml属性中有一个默认的animateLayoutChanges属性,设置该属性,可以添加ViewGroup增加view的过渡效果:

<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:orientation="vertical">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="add"
android:text="Add Button"/>
</LinearLayout>

3.LayoutAnimation动画

通过设置LayoutAnimation也同样可以实现布局动画效果

public class AnimateLayoutAnimation extends Activity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.animate_layout_animation);
         
        LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
        ScaleAnimation sa = new ScaleAnimation(0, 1, 0, 1);
        sa.setDuration(2000);
        // 第二个参数dely : the delay by which each child's animation must be offset
        LayoutAnimationController lac = new LayoutAnimationController(sa, 0.5F);
        // 设置显示的顺序 这个必须要在dely不为0的时候才有效
        lac.setOrder(LayoutAnimationController.ORDER_NORMAL);
        ll.setLayoutAnimation(lac);
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Animation Animation类是所有动画(scale、alpha、translate、rotate)的基...
    四月一号阅读 5,908评论 0 10
  • Android框架提供了两种类型的动画:View Animation(也称视图动画)和Property Anima...
    RxCode阅读 5,628评论 1 5
  • 这段时间正好要做些动画,于是把属性动画重新学习了一遍,做些总结 1. 前言 Android动画分为Frame An...
    梦sora阅读 9,463评论 0 9
  • 3.0以前,android支持两种动画模式,tween animation,frame animation,在an...
    Ten_Minutes阅读 5,601评论 0 4
  • 1 背景 不能只分析源码呀,分析的同时也要整理归纳基础知识,刚好有人微博私信让全面说说Android的动画,所以今...
    未聞椛洺阅读 7,657评论 0 10