Android 布局动画(Layout Animations)


转载http://blog.csdn.net/harvic880925/article/details/50785786

这篇将给大家讲解如何给容器中的控件应用统一动画。即在容器中控件出现时,不必为每个控件添加进入动画,可以在容器中为其添加统一的进入和退出动画。 
这里写图片描述 
从上面的示例动画也可以看出,listview中的数据在进入时就加入了统一动画,下面我们就来看看这些是怎么来实现的吧。 
这篇我们将讲述有关普通viewGroup添加进入统一动画的LayoutAnimation和针对grideView添加进入动画的gridLayoutAnimation; 
LayoutAnimation和gridLayoutAnimation在API 1中就有的函数。所有大家不必担心他们的所能使用的api等级;也正因为他们是在API 1中就引入了,所以他们也只能使用animtion来做动画,而不能使用animator。

一、LayoutAnimation的xml实现——layoutAnimation标签

1、概述

这部分,我们就来看看layoutAnimation标签的用法,要使用layoutAnimation只需要两步: 
第一:定义一个layoutAnimation的animation文件,如:(anim/layout_animation.xml)

<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
                 android:delay="1"
                 android:animationOrder="normal"
                 android:animation="@anim/slide_in_left"/>

有关它的具体意义,我们后面会讲。 
第二步:在viewGroup类型的控件中,添加Android:layoutAnimation=”@anim/layout_animation”,如:

<ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layoutAnimation="@anim/layout_animation"
        />

2、示例

这部分,我们将要实现的效果图如下: 
这里写图片描述 
从效果图中,可以看出两点: 
- listview中各个item从左至右滑入位置 
- 动画仅在第一次创建时有用,后期加入的数据,将不会再有动画(这个问题最后再讲)

这里添加的layoutAnimation,与上面的layout_animation.xml文件一样:

<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
                 android:delay="1"
                 android:animationOrder="normal"
                 android:animation="@anim/slide_in_left"/>
其中的@anim/slide_in_left对应代码为:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000">
    <translate android:fromXDelta="-50%p" android:toXDelta="0"/>
    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"/>
</set>
这部分实现的效果是,让控件从左边50%的位置进入屏幕,同时透明度从0变到1;动画总时长为1000毫秒。 
然后看main.xml的布局代码,根据效果图中也很容易看出布局代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="刷新list"/>

    <ListView
            android:id="@+id/listview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layoutAnimation="@anim/layout_animation"/>
</LinearLayout>

这里最重要的是,在listView中添加上 android:layoutAnimation=”@anim/layout_animation”来指定创建布局时,其中的子item所使用的动画。 
最后是MyActivity中填充listview的代码:

public class MyActivity extends Activity {

    private ListView mListView;
    private ArrayAdapter mAdapter;
    private Button mAddListBtn;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mListView = (ListView) findViewById(R.id.listview);
        mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, getData());
        mListView.setAdapter(mAdapter);

        mAddListBtn = (Button)findViewById(R.id.addlist);
        mAddListBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mAdapter.addAll(getData());
            }
        });
    }

    private List<String> getData() {
        List<String> data = new ArrayList<String>();
        data.add("测试数据1");
        data.add("测试数据2");
        data.add("测试数据3");
        data.add("测试数据4");

        return data;
    }
}

这段代码理解起来难度不大,主要就是两个点,第一:填充listview,第二在点击添加list数据按钮时,向Listview添加新的数据。 
最终的效果图在本部分开头就已经给出。通过这个例子,我们可以知道最重要的一点:android:layoutAnimation只在viewGroup创建的时候,才会对其中的item添加动画。在创建成功以后,再向其中添加item将不会再有动画。 
我们可以看出,只需要在viewGroup控件中添加android:layoutAnimation="@anim/layout_animation",就可以实现其容器内部控件创建时的动画。

3、layoutAnimation各字段意义

上面我们讲了layoutAnimation的使用方法,下面我们就来看看layoutAnimation标签中各个字段的意义。 
在layoutAnimation中,只有三个字段是有效的,分别是:android:delay、android:animationOrder和android:animation;其它诸如android:duration、android:interpolator等针对animation的字段都是无效的。下面我们结合上面的layoutAnimation代码,来看一下各个字段的具体意义:

<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
                 android:delay="1"
                 android:animationOrder="normal"
                 android:animation="@anim/slide_in_left"/>
  • delay:每个Item的动画开始延时,取值是android:animation所指定动画时长的倍数,取值类型可以是float类型,也可以是百分数,默认是0.5;比如我们这里指定的动画是@anim/slide_in_left,而在slide_in_left.xml中指定android:duration=”1000”,即单次动画的时长是1000毫秒,而我们在这里的指定android:delay=”1”,即一个Item的动画会在上一个item动画完成后延时单次动画时长的一倍时间开始,即延时1000毫秒后开始。
  • animationOrder:指viewGroup中的控件动画开始顺序,取值有normal(正序)、reverse(倒序)、random(随机)
  • animation:指定每个item入场所要应用的动画。仅能指定res/aim文件夹下的animation定义的动画,不可使用animator动画

这里最难理解的参数应该是android:delay,它是指viewGroup中各个item开始动画的时间延迟,取值是Item动画时长的倍数。其中item动画是通过android:animation指定的。 
其次就是animationOrder的三种次序,其实也没什么难度,我们就直接通过动画来看看它们的区别吧。上面的效果图中,我们演示的normal(正序),下面我们再来看看reverse和random的效果图: 
android:animationOrder=”reverse”(倒序) 
这里写图片描述 
android:animationOrder=”random”(随机) 
这里写图片描述 

二、LayoutAnimation的代码实现——LayoutAnimationController

1、概述

上面我们讲过了LayoutAnimation的xml实现方式,下面来看看LayoutAnimation的代码实现方式。 
首先,xml中layoutAnimation标签所对应的类为LayoutAnimationController;它有两个构造函数:

public LayoutAnimationController(Animation animation)
public LayoutAnimationController(Animation animation, float delay)


很容易理解,animation对应标签中的android:animation属性,delay对应标签中的android:delay属性。 
LayoutAnimationController的函数如下:

/**
 * 设置animation动画
 */
public void setAnimation(Animation animation)
/**
 * 设置单个item开始动画延时
 */
public void setDelay(float delay)
/**
 * 设置viewGroup中控件开始动画顺序,取值为ORDER_NORMAL、ORDER_REVERSE、ORDER_RANDOM
 */
public void setOrder(int order)

2、示例

同样以上面的例子为例,把xml实现改成代码实现。

public class MyActivity extends Activity {

    private ListView mListView;
    private ArrayAdapter mAdapter;

    private Button mAddListBtn;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mListView = (ListView) findViewById(R.id.listview);
        mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, getData());
        mListView.setAdapter(mAdapter);

        mAddListBtn = (Button)findViewById(R.id.addlist);
        mAddListBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mAdapter.addAll(getData());
            }
        });


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

    private List<String> getData() {

        List<String> data = new ArrayList<String>();
        data.add("测试数据1");
        data.add("测试数据2");
        data.add("测试数据3");
        data.add("测试数据4");

        return data;
    }
}


这段代码中,在填充listview的代码都是与xml的实现方式相同的,关键是填充后,开始给listview设置LayoutAnimationController。


补充:

LayoutAnimationListener监听器,只执行onAnimationStart,onAnimationEnd方法

		//LayoutAnimationController controller = AnimationUtils.loadLayoutAnimation(this, R.anim.layout_animation);
		//Animation animation = AnimationUtils.loadAnimation(this,R.anim.slide_in_left);
		AlphaAnimation animation = new AlphaAnimation(0f, 1.0f);
		animation.setDuration(2000);
		animation.setFillAfter(true);
		animation.setStartOffset(200);
		animation.setInterpolator(new BounceInterpolator());
		LayoutAnimationController controller  = new LayoutAnimationController(animation, 0.1f);
		controller.setOrder(LayoutAnimationController.ORDER_RANDOM);
		mListView.setLayoutAnimation(controller);
		mListView.startLayoutAnimation();
		mListView.setLayoutAnimationListener(new Animation.AnimationListener() {
			@Override
			public void onAnimationStart(Animation animation) {
				Log.i("Animation", animation.getDuration()+"");
			}
			
			@Override
			public void onAnimationRepeat(Animation animation) {
			}
			
			@Override
			public void onAnimationEnd(Animation animation) {
				Log.i("Animation", animation.getFillAfter() + "");
			}
		});



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值