Layout动画:在android布局发生变化时添加动画效果

原文:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0318/1594.html

layout动画在每次布局发生变化的时候系统调用的一个预加载动画效果,使用layout动画可以让布局的变化过度看起来更自然。使用起来很简单,只需在控件中添加一个属性就可以了,系统默认是不会启动layout动画的,因此我们平时的应用中不会产生这个效果。

当然,如果你想自定义一下这个动画效果,那就必须在代码中自己写了:新建一个LayoutTransition对象,调用setLayoutTransition()方法来为layout设置动画。

下面是在xml中通过设置属性得到的默认动画效果:

这里写图片描述

使用方法:

在activity的xml中,设置android:animateLayoutChanges属性:

<LinearLayout android:id="@+id/container"
    android:animateLayoutChanges="true"
    ...
/>

这样,当该LinearLayout中的布局发生变化时,将会有动画效果。

什么情况下布局会在运行时改变呢,一般都是你的代码中调用了addView 之类的方法:

private ViewGroup mContainerView;
...
private void addItem() {
    View newView;
    ...
    mContainerView.addView(newView, 0);
}

好了,这个东西很简单,只是平时很少注意到,只要记得android自带这个功能就行了,免得到时候自己去实现。


Android LayoutAnimation使用及扩展

在Android中,最简单的动画就是补间动画了。通过补间动画,可以对一个控件进行位移、缩放、旋转、改变透明度等动画。但是补间动画只能对一个控件使用,如果要对某一组控件播放一样的动画的话,可以考虑layout-animation。

LayoutAnimation

layout-animation可由xml和代码两种方式配置:

XML配置

由于layout-animation是对于某一组控件的操作,就需要一个基本的动画来定义单个控件的动画。另外还可以定义动画的显示顺序和延迟:

<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
        android:delay="30%"
        android:animationOrder="reverse"
        android:animation="@anim/slide_right"/>

其中

  1. android:delay表示动画播放的延时,既可以是百分比,也可以是float小数。
  2. android:animationOrder表示动画的播放顺序,有三个取值normal(顺序)、reverse(反序)、random(随机)。
  3. android:animation指向了子控件所要播放的动画。

  4. 上述步骤完成之后,就可以将layout-animation应用到ViewGroup中,xml布局添加下面一行就ok:
android:layoutAnimation="@anim/list_anim_layout"

这样在加载布局的时候就会自动播放layout-animtion。

代码配置

如果在xml中文件已经写好LayoutAnimation,可以使用AnimationUtils直接加载:

AnimationUtils.loadLayoutAnimation(context, id)

另外还可以手动java代码编写,如:

//通过加载XML动画设置文件来创建一个Animation对象;
Animation animation=AnimationUtils.loadAnimation(this, R.anim.slide_right);   //得到一个LayoutAnimationController对象;
   LayoutAnimationController controller = new LayoutAnimationController(animation);   //设置控件显示的顺序;
   controller.setOrder(LayoutAnimationController.ORDER_REVERSE);   //设置控件显示间隔时间;
   controller.setDelay(0.3);   //为ListView设置LayoutAnimationController属性;
   listView.setLayoutAnimation(controller);
   listView.startLayoutAnimation();

通过代码设置可以达到同样效果。

扩展

前几天遇到一个需求,将动画顺序改为左上到右下角展开,例如Material Design中这个样子。

这里写图片描述

虽然一个个按顺序播放页可以实现,但也太low了,就希望能够找一个简便的方法。(PS. 个人崇尚简约就是美)

仔细观察,很明显就是一个LayoutAnimation,但是LayoutAnimation默认只有三种顺序,即顺序逆序和随机,不能满足需求。去翻翻源码看它是怎么实现的,有没有提供方法自定义顺序?结果翻到了一个LayoutAnimationController#getTransformedIndex(AnimationParameters params)方法,返回值就是播放动画的顺序。并且这个方法是protected的,明显就是可由子类来扩展。既然找到了方法,那么就去实现它:

/**
     * custom LayoutAnimationController for playing child animation
     * in any order.
     *
     */
public class CustomLayoutAnimationController extends LayoutAnimationController {

    // 7 just lucky number
    public static final int ORDER_CUSTOM  = 7;

    private Callback onIndexListener;

    public void setOnIndexListener(OnIndexListener onIndexListener) {
        this.onIndexListener = onIndexListener;
    }

    public CustomLayoutAnimationController(Animation anim) {
        super(anim);
    }

    public CustomLayoutAnimationController(Animation anim, float delay) {
        super(anim, delay);
    }

    public CustomLayoutAnimationController(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * override method for custom play child view animation order
    */
    protected int getTransformedIndex(AnimationParameters params) {
        if(getOrder() == ORDER_CUSTOM &amp;&amp; onIndexListener != null) {
            return onIndexListener.onIndex(this, params.count, params.index);
        } else {
            return super.getTransformedIndex(params);
        }
    }

    /**
     * callback for get play animation order
     *
     */
    public static interface Callback{

        public int onIndex(CustomLayoutAnimationController controller, int count, int index);
    }
}

通过复写getTransformedIndex方法,添加自定义顺序ORDER_CUSTOM,让callback自定义控件播放动画的顺序,即可以达到任何想要的效果。

总结

Android在设计的时候,提供了很好的扩展性。各种组件都可以按需求扩展。可能用的更多的是还是View.onDraw(Canvas canvas)方法,但不仅仅是view,对于其他组件,也可以随意的扩展。很多时候,并不一定需要自定义很多空间、功能之类的,往往扩展一些简单的组件就能达到自己想要的结果。

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值