Android优化视觉---伸展动画

第一次写博客, 不足之处望多多包含本小弟弟.

之所以开始学博客,源于看过一BAT大神写的一篇文章有感,从来不用脑机, 用笔记, 不得不承认这是个事实, 所以想想也挺对的.本人不算聪明,希望勤能补拙了.
为什么写动画?

相信很多刚开始接触工作的同学也有感触, 动画这种东西看起来酷炫, 自己写就难了, 最后还要搞得怀疑下 自己到底是技术问题还是审美问题?总之,踩的坑相信也不少.本宝宝也是受害人之一,不废话,直接进入正题.

首先,Android中动画大概分为三种:  补间动画,属性动画,帧动画. 后者用的场景非常少.   使用最多的是前面两者, 其中属性动画 在官方API中只支持到API 14 也就是Android 4.0. 当然,有大神已经给出了兼容API14以下的兼容包,用法几乎一致. 使用最多的是前面两者, 其中属性动画 在官方API中只支持到API 14 也就是Android 4.0. 当然,有大神已经给出了兼容API14以下的兼容包,用法几乎一致.《NineOldAndroids属性动画》。

那么,在开发中,如果要重新设置某一个view的高,一般的做法是 

ViewGroup.LayoutParams params = content.getLayoutParams();
            params.height=value;
            content.setLayoutParams(params);

实现重置content的高度, 但是,在真实机子上效果并不是那么好,感觉变幻很生硬有木有?那么这里就可以使用属性动画解决这个问题。

为什么不用补间动画? 如果使用补间动画,也可以达到伸展效果。这时候会出现2个问题:

第一,补间动画在视觉上是达到了你想要的动画效果, 但是在执行的过程中程序内部没有调用onmeasure()和 onlayout(),它只调用了ondraw(),也就是说,这时候你看到的并非是你看到的,它的属性没有改变. view的top,left,right.bottom 4个属性并没有改变。

第二,这个问题的出现,其实也是因为第一个原因, 在做动画的view周围的所有view,其位置并没有跟着动画view的位置或形状的改变而改变,这是个大问题,所以排除使用补间动画,改用属性动画。

好的,BB够了,请品尝代码。。。

主界面是activity_main.xml 是一个LinearLayout 包裹3个View ,标题View,伸展内容View,尾部View。

<pre name="code" class="html"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent"
    tools:context="com.demotest.testdemo.MainActivity">

    <RelativeLayout
        android:id="@+id/toggle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:gravity="center_vertical"
            android:background="#cccccc"
            android:text="标题"/>
        <ImageView
            android:id="@+id/arrow"
            android:layout_width="20dp"
            android:layout_centerVertical="true"
            android:layout_alignParentRight="true"
            android:layout_marginRight="10dp"
            android:layout_height="20dp"
            android:src="@drawable/down_arrow"/>

    </RelativeLayout>


    <LinearLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:background="#666666"
        android:textColor="#ffffff"
        android:text="Hello World!"
        android:orientation="horizontal"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:gravity="center_vertical"
        android:background="#ff0000"
        android:textColor="#ffffff"
        android:text="底部内容"/>

</LinearLayout>
</pre><pre>
 在MainActivity的onCreate方法中,初始化view,初始化动画content的初始状态。 
 

 
 
 
 
 
 
 点击标题,content响应: 
 

private void toggleContent(boolean animation) {
    content.measure(0, 0); //测量宽高
    int measuredHeight = content.getMeasuredHeight();

    if (isOpen) {
        //1.内容关闭
        if (animation) {

            //从打开到关闭做--收缩动画
            int start = measuredHeight;
            int end = 0;
            ValueAnimator animator = ValueAnimator.ofInt(start, end);
            animator.setDuration(400);
            animator.addUpdateListener(animationListener);
            animator.start();
            //2.标志旋转属性动画
            ObjectAnimator.ofFloat(arrow, "rotation", -180, 0).setDuration(400).start();

        } else {
            //无动画效果
            ViewGroup.LayoutParams params = content.getLayoutParams();
            params.height = 0;
            content.setLayoutParams(params);

            arrow.setRotation(0);

        }


    } else {
        //1.内容打开
        if (animation) {

            //从关闭到打开做--伸展动画
            int start = 0;
            int end = measuredHeight;
            ValueAnimator animator = ValueAnimator.ofInt(start, end);
            animator.setDuration(400);
            animator.addUpdateListener(animationListener);
            animator.start();
            //2.标志旋转属性动画
            ObjectAnimator.ofFloat(arrow, "rotation", 0, 180).setDuration(400).start();
        } else {
            //无动画效果
            ViewGroup.LayoutParams params = content.getLayoutParams();
            params.height = measuredHeight;
            content.setLayoutParams(params);

            arrow.setRotation(180);
        }


    }

    isOpen = !isOpen;
}
注册动画过程监听器,不停的设置LayoutParams的height属性。实现伸展效果。

private ValueAnimator.AnimatorUpdateListener animationListener = new android.animation.ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        int value = (int) animation.getAnimatedValue();
        ViewGroup.LayoutParams params = content.getLayoutParams();
        params.height = value;
        content.setLayoutParams(params);

    }
};

看效果:



你可能感兴趣的:(动画,android,伸展)