从布局动画引入ListView滑动时,每一Item项的显示动画

来源:互联网 发布:mysql 生成连续数字 编辑:程序博客网 时间:2024/06/05 16:10

原文地址:http://blog.csdn.net/zuiwuyuan/article/details/48010197


今天我主要给大家引入一个APP的ListView的动画效果: 当展示ListView时,Listview的每一个列表项都按照规定的动画显示出来。

  说起来比较抽象,先给大家看一个动画效果,这是APP窝牛装修的ListView显示动画:


    有木有觉得很酷炫?有木有啊!?


一、Layout Animation

    所谓的布局动画,其实就是为ViewGroup添加显示动画效果,主要用过LayoutAnimationController来控制实现。LayoutAnimationController用于为一个Layout里面的控件,或者是一个ViewGroup里面的控件设置动画效果,可以在XML文件中设置,亦可以在Java代码中设置。


1.1 在XML文件中设置布局动画


  首先,我们在res/anim文件夹下建立一个list_anim_layout.xml文件,该文件就是布局动画控制器。

[html] view plain copy
 print?
  1. <layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:delay="30%"  
  3.     android:animationOrder="random"  
  4.     android:animation="@anim/slide_right" />  

android:delay  子类动画时间间隔 (延迟)   70% 也可以是一个浮点数 如“1.2”等。
android:animationOrder="random"   子类的显示方式 random表示随机。
android:animationOrder 的取值有 
     normal 0    默认
     reverse 1 倒序
     random 2   随机
android:animation="@anim/slide_right" 表示列表项显示时的具体动画是什么!

下面,我们定义每一个列表项显示时的动画效果吧,及slide_right.xml:

[html] view plain copy
 print?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <set xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:interpolator="@android:anim/accelerate_interpolator">  
  4.   
  5.     <translate  
  6.         android:duration="3000"  
  7.         android:fromXDelta="100%p"  
  8.         android:toXDelta="0%p" />  
  9. </set>  

显示的效果为ListView第一次出现的时候为 item随机出现 每个Item都是从右边的区域向左滑动到显示的地方。

接下来,你只需要把这个布局动画,指定到ViewGroup上就好了:

[html] view plain copy
 print?
  1. <ListView  
  2.         android:id="@+id/listView"  
  3.         android:layout_width="match_parent"  
  4.         android:layout_height="match_parent"  
  5.         android:layoutAnimation="@anim/list_anim_layout"  
  6.         >  
  7. </ListView>  
就这么简单就完成了,快来看下效果吧:




1.2 在Java代码中实现布局动画

    在Java代码中实现布局动画并无难度,只要熟悉几个API的使用即可。 关于动画的定义和上文一致,只是,你不需要再在把控制动画应用到listview中了,即android:layoutAnimation="@anim/list_anim_layout"这行代码可以删除。

    接下来,需要在Java代码中进行配置:

[java] view plain copy
 print?
  1. private void startLayoutAnim() {  
  2.     //通过加载XML动画设置文件来创建一个Animation对象;  
  3.     Animation animation = AnimationUtils.loadAnimation(this, R.anim.slide_right);  
  4.     //得到一个LayoutAnimationController对象;  
  5.     LayoutAnimationController lac = new LayoutAnimationController(animation);  
  6.     //设置控件显示的顺序;  
  7.     lac.setOrder(LayoutAnimationController.ORDER_REVERSE);  
  8.     //设置控件显示间隔时间;  
  9.     lac.setDelay(1);  
  10.     //为ListView设置LayoutAnimationController属性;  
  11.     listView.setLayoutAnimation(lac);  
  12. }  


    观察下,效果和之前使用xml文件肯定是一致的了。

    

    介绍到这里,可能有人会有疑问了,博文一开始介绍的“窝牛装修”的那种效果,是每一个列表项显示的时候才会显示动画。我们这个确实所有的列表项的动画一起都显示了,只是显示顺序不同而已。 通过我们这种方法,怎么可能会达到那种效果呢?

    确实,通过布局动画,没办法控制每一个Item在加载时才显示动画。那该如何是好呢?

    兄弟们,换个思路吧,如果布局动画完成不了,何必不直接用简单的补间动画,再结合每个列表项的显示控制,来实现窝牛装修列表显示的效果呢? 

    那有人会问了,怎么知道每一个列表项何时才加载么?

    你难道忘了BaseAdapter的getView()方法了么?

    没错,每当一个列表项显示时,都会主动调用BaseAdaper的getView()方法。


二、仿窝牛装修List列表的动画效果

    首先,我们定义一个动画资源,该动画即是列表项显示时的动画:woniu_list_item.xml

[html] view plain copy
 print?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <set xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:interpolator="@android:anim/accelerate_interpolator"  
  4.     >  
  5.     <!--    woniu list item animation    -->  
  6.   
  7.     <translate  
  8.         android:duration="500"  
  9.         android:fromXDelta="0"  
  10.         android:fromYDelta="100"  
  11.         android:toXDelta="0"  
  12.         android:toYDelta="0" />  
  13. </set>  

    该平移动画表示,从下往上,垂直平移100px,时间为500毫秒。

    接下来,我们需要在BaseAdapter的getView()方法里,去使用该动画:

[java] view plain copy
 print?
  1. import android.content.Context;  
  2. import android.view.LayoutInflater;  
  3. import android.view.View;  
  4. import android.view.ViewGroup;  
  5. import android.view.animation.Animation;  
  6. import android.view.animation.AnimationUtils;  
  7. import android.widget.BaseAdapter;  
  8. import android.widget.ImageView;  
  9. import android.widget.TextView;  
  10.   
  11.   
  12. import java.util.List;  
  13.   
  14. public class WoniuListAdapter extends BaseAdapter {  
  15.   
  16.     private Context mContext;  
  17.   
  18.     private LayoutInflater mInflater;  
  19.   
  20.     private List<WoniuSimple> mDatas;  
  21.   
  22.     private Animation animation;  
  23.   
  24.     public WoniuListAdapter(Context context, List<WoniuSimple> datas) {  
  25.         mContext = context;  
  26.         mInflater = LayoutInflater.from(mContext);  
  27.         mDatas = datas;  
  28.   
  29.         animation = AnimationUtils.loadAnimation(mContext, R.anim.woniu_list_item);  
  30.     }  
  31.   
  32.     @Override  
  33.     public int getCount() {  
  34.         return (mDatas != null ? mDatas.size() : 0);  
  35.     }  
  36.   
  37.     @Override  
  38.     public Object getItem(int position) {  
  39.         return (mDatas != null ? mDatas.get(position) : null);  
  40.     }  
  41.   
  42.     @Override  
  43.     public long getItemId(int position) {  
  44.         return position;  
  45.     }  
  46.   
  47.     @Override  
  48.     public View getView(final int position, View convertView, ViewGroup parent) {  
  49.         ViewHolder holder = null;  
  50.         int type = getItemViewType(position);  
  51.         if (convertView == null) {  
  52.   
  53.             // 下拉项布局  
  54.             convertView = mInflater.inflate(R.layout.list_item_woniu, null);  
  55.   
  56.             holder = new ViewHolder();  
  57.   
  58.             holder.tem_img = (ImageView) convertView.findViewById(R.id.tem_img);  
  59.             holder.text_name = (TextView) convertView.findViewById(R.id.text_name);  
  60.             holder.text_name = (TextView) convertView.findViewById(R.id.text_name);  
  61.   
  62.             convertView.setTag(holder);  
  63.   
  64.         } else {  
  65.             holder = (ViewHolder) convertView.getTag();  
  66.         }  
  67.   
  68.         convertView.startAnimation(animation);  
  69.   
  70.         final WoniuSimple materialSimple = mDatas.get(position);  
  71.   
  72.         if (materialSimple != null) {  
  73. //            holder.tem_img.setImageResource(R.mipmap.assist_default_img);  
  74. //            holder.text_name.setText(materialSimple.name);  
  75. //            holder.text_mobile.setText(materialSimple.mobile);  
  76.         }  
  77.   
  78.   
  79.         return convertView;  
  80.     }  
  81.   
  82.     class ViewHolder {  
  83.   
  84.         ImageView tem_img;  
  85.   
  86.         TextView text_name;  
  87.   
  88.         TextView text_mobile;  
  89.     }  
  90.   
  91. }  

    我们来简要分析应用动画的地方: 1、我们Adapter的构造方法里加载了之前定义的动画,活的Animation对象。 2、 我们在getView方法里,为convertView设置并启动Animation,即convertView.startAnimation(animation)。

    够简单吧,只是这么两行代码,就可以实现在加载每一个View Item时启动动画效果。

    可是,我们发现,这并不是非常完美的实现,为啥这么说呢?

    因为你此刻往上滑动列表,会发现,已经加载过的Item的动画还会再次启动执行一次。这个体验太糟糕了。为啥会出现这种情况啊?

    因为getVIew方法的调用时机会对动画产生影响。Adapter中的getView方法,会在每一个item处于可见状态时调用,所以无论你上滑还是下滑,都会重复调用getView方法(这也是ListView为啥在使用时要进行优化的地方)。

    所以,为了解决刚刚发生的问题,我们可以设置标识,进行判断,已经加载过的view的动画不再进行启动加载。

    完整的代码如下:

[java] view plain copy
 print?
  1. package com.lnyp.layoutanimation;  
  2.   
  3. import android.content.Context;  
  4. import android.view.LayoutInflater;  
  5. import android.view.View;  
  6. import android.view.ViewGroup;  
  7. import android.view.animation.Animation;  
  8. import android.view.animation.AnimationUtils;  
  9. import android.widget.BaseAdapter;  
  10. import android.widget.ImageView;  
  11. import android.widget.TextView;  
  12.   
  13.   
  14. import java.util.HashMap;  
  15. import java.util.List;  
  16. import java.util.Map;  
  17.   
  18. public class WoniuListAdapter extends BaseAdapter {  
  19.   
  20.     private Context mContext;  
  21.   
  22.     private LayoutInflater mInflater;  
  23.   
  24.     private List<WoniuSimple> mDatas;  
  25.   
  26.     private Animation animation;  
  27.   
  28.     private Map<Integer, Boolean> isFrist;  
  29.   
  30.     public WoniuListAdapter(Context context, List<WoniuSimple> datas) {  
  31.         mContext = context;  
  32.         mInflater = LayoutInflater.from(mContext);  
  33.         mDatas = datas;  
  34.   
  35.         animation = AnimationUtils.loadAnimation(mContext, R.anim.woniu_list_item);  
  36.         isFrist = new HashMap<Integer, Boolean>();  
  37.     }  
  38.   
  39.     @Override  
  40.     public int getCount() {  
  41.         return (mDatas != null ? mDatas.size() : 0);  
  42.     }  
  43.   
  44.     @Override  
  45.     public Object getItem(int position) {  
  46.         return (mDatas != null ? mDatas.get(position) : null);  
  47.     }  
  48.   
  49.     @Override  
  50.     public long getItemId(int position) {  
  51.         return position;  
  52.     }  
  53.   
  54.     @Override  
  55.     public View getView(final int position, View convertView, ViewGroup parent) {  
  56.         ViewHolder holder = null;  
  57.         int type = getItemViewType(position);  
  58.         if (convertView == null) {  
  59.   
  60.             // 下拉项布局  
  61.             convertView = mInflater.inflate(R.layout.list_item_woniu, null);  
  62.   
  63.             holder = new ViewHolder();  
  64.   
  65.             holder.tem_img = (ImageView) convertView.findViewById(R.id.tem_img);  
  66.             holder.text_name = (TextView) convertView.findViewById(R.id.text_name);  
  67.             holder.text_name = (TextView) convertView.findViewById(R.id.text_name);  
  68.   
  69.             convertView.setTag(holder);  
  70.   
  71.         } else {  
  72.             holder = (ViewHolder) convertView.getTag();  
  73.         }  
  74.   
  75.         // 如果是第一次加载该view,则使用动画  
  76.         if (isFrist.get(position) == null || isFrist.get(position)) {  
  77.   
  78.             convertView.startAnimation(animation);  
  79.             isFrist.put(position, false);  
  80.         }  
  81.   
  82.         final WoniuSimple materialSimple = mDatas.get(position);  
  83.   
  84.         if (materialSimple != null) {  
  85. //            holder.tem_img.setImageResource(R.mipmap.assist_default_img);  
  86. //            holder.text_name.setText(materialSimple.name);  
  87. //            holder.text_mobile.setText(materialSimple.mobile);  
  88.         }  
  89.   
  90.   
  91.         return convertView;  
  92.     }  
  93.   
  94.     class ViewHolder {  
  95.   
  96.         ImageView tem_img;  
  97.   
  98.         TextView text_name;  
  99.   
  100.         TextView text_mobile;  
  101.     }  
  102.   
  103. }  

     看到了么,加了一个isFirst进行判断,这样,就可以有效控制动画的显示了。效果如下:


   

结束:

     本文我主要介绍了两个部分,一个是Layout Animation布局动画,使用布局动画可以控制VIew Groups中的每一个数据的显示动画; 还一个就是实战,仿“窝牛装修”ListView滑动时每一个Item滑动进入可见状态的动画效果。通过这两个动画示例,我相信可以帮助大家更好的处理动画,克服“动画恐惧症”。


源码下载地址(免费):http://download.csdn.net/detail/zuiwuyuan/9051895

0 0
原创粉丝点击