Android Animation动画实战(一): 从布局动画引入ListView滑动时,每一Item项的显示动画
前言:
之前,我已经写了两篇博文,给大家介绍了Android的基础动画是如何实现的,如果还不清楚的,可以点击查看:Android Animation动画详解(一): 补间动画 及 Android
Animation动画详解(二): 组合动画特效 。 已经熟悉了基础动画的实现后,便可以试着去实现常见APP中出现过的那些精美的动画。今天我主要给大家引入一个APP的ListView的动画效果: 当展示ListView时,Listview的每一个列表项都按照规定的动画显示出来。
说起来比较抽象,先给大家看一个动画效果,这是APP窝牛装修的ListView显示动画:
有木有觉得很酷炫?有木有啊!?
一、Layout Animation
所谓的布局动画,其实就是为ViewGroup添加显示动画效果,主要用过LayoutAnimationController来控制实现。LayoutAnimationController用于为一个Layout里面的控件,或者是一个ViewGroup里面的控件设置动画效果,可以在XML文件中设置,亦可以在Java代码中设置。
1.1 在XML文件中设置布局动画
首先,我们在res/anim文件夹下建立一个list_anim_layout.xml文件,该文件就是布局动画控制器。
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:delay="30%"
android:animationOrder="random"
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:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"> <translate
android:duration="3000"
android:fromXDelta="100%p"
android:toXDelta="0%p" />
</set>
显示的效果为ListView第一次出现的时候为 item随机出现 每个Item都是从右边的区域向左滑动到显示的地方。
接下来,你只需要把这个布局动画,指定到ViewGroup上就好了:
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutAnimation="@anim/list_anim_layout"
>
</ListView>
就这么简单就完成了,快来看下效果吧:
1.2 在Java代码中实现布局动画
在Java代码中实现布局动画并无难度,只要熟悉几个API的使用即可。 关于动画的定义和上文一致,只是,你不需要再在把控制动画应用到listview中了,即android:layoutAnimation="@anim/list_anim_layout"这行代码可以删除。
接下来,需要在Java代码中进行配置:
private void startLayoutAnim() {
//通过加载XML动画设置文件来创建一个Animation对象;
Animation animation = AnimationUtils.loadAnimation(this, R.anim.slide_right);
//得到一个LayoutAnimationController对象;
LayoutAnimationController lac = new LayoutAnimationController(animation);
//设置控件显示的顺序;
lac.setOrder(LayoutAnimationController.ORDER_REVERSE);
//设置控件显示间隔时间;
lac.setDelay(1);
//为ListView设置LayoutAnimationController属性;
listView.setLayoutAnimation(lac);
}
观察下,效果和之前使用xml文件肯定是一致的了。
介绍到这里,可能有人会有疑问了,博文一开始介绍的“窝牛装修”的那种效果,是每一个列表项显示的时候才会显示动画。我们这个确实所有的列表项的动画一起都显示了,只是显示顺序不同而已。 通过我们这种方法,怎么可能会达到那种效果呢?
确实,通过布局动画,没办法控制每一个Item在加载时才显示动画。那该如何是好呢?
兄弟们,换个思路吧,如果布局动画完成不了,何必不直接用简单的补间动画,再结合每个列表项的显示控制,来实现窝牛装修列表显示的效果呢?
那有人会问了,怎么知道每一个列表项何时才加载么?
你难道忘了BaseAdapter的getView()方法了么?
没错,每当一个列表项显示时,都会主动调用BaseAdaper的getView()方法。
二、仿窝牛装修List列表的动画效果
首先,我们定义一个动画资源,该动画即是列表项显示时的动画:woniu_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
>
<!-- woniu list item animation --> <translate
android:duration="500"
android:fromXDelta="0"
android:fromYDelta="100"
android:toXDelta="0"
android:toYDelta="0" />
</set>
该平移动画表示,从下往上,垂直平移100px,时间为500毫秒。
接下来,我们需要在BaseAdapter的getView()方法里,去使用该动画:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView; import java.util.List; public class WoniuListAdapter extends BaseAdapter { private Context mContext; private LayoutInflater mInflater; private List<WoniuSimple> mDatas; private Animation animation; public WoniuListAdapter(Context context, List<WoniuSimple> datas) {
mContext = context;
mInflater = LayoutInflater.from(mContext);
mDatas = datas; animation = AnimationUtils.loadAnimation(mContext, R.anim.woniu_list_item);
} @Override
public int getCount() {
return (mDatas != null ? mDatas.size() : 0);
} @Override
public Object getItem(int position) {
return (mDatas != null ? mDatas.get(position) : null);
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int type = getItemViewType(position);
if (convertView == null) { // 下拉项布局
convertView = mInflater.inflate(R.layout.list_item_woniu, null); holder = new ViewHolder(); holder.tem_img = (ImageView) convertView.findViewById(R.id.tem_img);
holder.text_name = (TextView) convertView.findViewById(R.id.text_name);
holder.text_name = (TextView) convertView.findViewById(R.id.text_name); convertView.setTag(holder); } else {
holder = (ViewHolder) convertView.getTag();
} convertView.startAnimation(animation); final WoniuSimple materialSimple = mDatas.get(position); if (materialSimple != null) {
// holder.tem_img.setImageResource(R.mipmap.assist_default_img);
// holder.text_name.setText(materialSimple.name);
// holder.text_mobile.setText(materialSimple.mobile);
} return convertView;
} class ViewHolder { ImageView tem_img; TextView text_name; TextView text_mobile;
} }
我们来简要分析应用动画的地方: 1、我们Adapter的构造方法里加载了之前定义的动画,活的Animation对象。 2、 我们在getView方法里,为convertView设置并启动Animation,即convertView.startAnimation(animation)。
够简单吧,只是这么两行代码,就可以实现在加载每一个View Item时启动动画效果。
可是,我们发现,这并不是非常完美的实现,为啥这么说呢?
因为你此刻往上滑动列表,会发现,已经加载过的Item的动画还会再次启动执行一次。这个体验太糟糕了。为啥会出现这种情况啊?
因为getVIew方法的调用时机会对动画产生影响。Adapter中的getView方法,会在每一个item处于可见状态时调用,所以无论你上滑还是下滑,都会重复调用getView方法(这也是ListView为啥在使用时要进行优化的地方)。
所以,为了解决刚刚发生的问题,我们可以设置标识,进行判断,已经加载过的view的动画不再进行启动加载。
完整的代码如下:
package com.lnyp.layoutanimation; import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView; import java.util.HashMap;
import java.util.List;
import java.util.Map; public class WoniuListAdapter extends BaseAdapter { private Context mContext; private LayoutInflater mInflater; private List<WoniuSimple> mDatas; private Animation animation; private Map<Integer, Boolean> isFrist; public WoniuListAdapter(Context context, List<WoniuSimple> datas) {
mContext = context;
mInflater = LayoutInflater.from(mContext);
mDatas = datas; animation = AnimationUtils.loadAnimation(mContext, R.anim.woniu_list_item);
isFrist = new HashMap<Integer, Boolean>();
} @Override
public int getCount() {
return (mDatas != null ? mDatas.size() : 0);
} @Override
public Object getItem(int position) {
return (mDatas != null ? mDatas.get(position) : null);
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int type = getItemViewType(position);
if (convertView == null) { // 下拉项布局
convertView = mInflater.inflate(R.layout.list_item_woniu, null); holder = new ViewHolder(); holder.tem_img = (ImageView) convertView.findViewById(R.id.tem_img);
holder.text_name = (TextView) convertView.findViewById(R.id.text_name);
holder.text_name = (TextView) convertView.findViewById(R.id.text_name); convertView.setTag(holder); } else {
holder = (ViewHolder) convertView.getTag();
} // 如果是第一次加载该view,则使用动画
if (isFrist.get(position) == null || isFrist.get(position)) { convertView.startAnimation(animation);
isFrist.put(position, false);
} final WoniuSimple materialSimple = mDatas.get(position); if (materialSimple != null) {
// holder.tem_img.setImageResource(R.mipmap.assist_default_img);
// holder.text_name.setText(materialSimple.name);
// holder.text_mobile.setText(materialSimple.mobile);
} return convertView;
} class ViewHolder { ImageView tem_img; TextView text_name; TextView text_mobile;
} }
看到了么,加了一个isFirst进行判断,这样,就可以有效控制动画的显示了。效果如下:
结束:
本文我主要介绍了两个部分,一个是Layout Animation布局动画,使用布局动画可以控制VIew Groups中的每一个数据的显示动画; 还一个就是实战,仿“窝牛装修”ListView滑动时每一个Item滑动进入可见状态的动画效果。通过这两个动画示例,我相信可以帮助大家更好的处理动画,克服“动画恐惧症”。
源码下载地址(免费):http://download.csdn.net/detail/zuiwuyuan/9051895
Android Animation动画实战(一): 从布局动画引入ListView滑动时,每一Item项的显示动画的更多相关文章
- android gridview布局,实现长按某一个,所有项都显示删除的图标
最近一直忙着项目开发,有段时间没有写博文了,今天想跟大家分享的是长按gridview中的某一项显示删除图标,此时点击某项便可删除,再长按取消删除图标. gridview的布局文件如下: <?xm ...
- Android Animation动画实战(二):从屏幕底部弹出PopupWindow
在这篇文章之前,我已经陆陆续续写了几篇博客,介绍了Android Animation是如何使用的,有还不明白的,可以点击查看: 1. Android Animation动画详解(一): 补间动画 2. ...
- Android ListView item项 显示动画
(1)使用LayoutAnimation 所谓的布局动画,其实就是为ViewGroup添加显示动画效果,主要用过LayoutAnimationController来控制实现.LayoutAnimati ...
- iOS自定义转场动画实战讲解
iOS自定义转场动画实战讲解 转场动画这事,说简单也简单,可以通过presentViewController:animated:completion:和dismissViewControllerA ...
- android - Animation详解
Drawable 最强大的功能是:显示Animation.AndroidSDK介绍了2种Animation: Tween Animation(渐变动画):通过对场景里的对象不断做图像变换(平移.缩放. ...
- Android RecyclerView使用 及 滑动时加载图片优化方案
1.控制线程数量 + 数据分页加载2.重写onScrollStateChanged方法 这个我们后面再谈,下面先来看看RecyclerView控件的使用及我们为什么选择使用它 RecyclerView ...
- [置顶]
android ListView包含Checkbox滑动时状态改变
题外话: 在xamarin android的开发中基本上所有人都会遇到这个小小的坎,的确有点麻烦,当时我也折腾了好一半天,如果你能看到这篇博客,说明你和我当初也是一样的焦灼,如果你想解决掉这个小小的坎 ...
- Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition
Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition Property animation系统还提供了对ViewGroup中的View改变 ...
- Android Animation(动画)
前言 Android 平台提供实现动画的解决方案(三种) 一.3.0以前,android支持两种动画: (1)Frame Animation:顺序播放事先做好的图像,与gif图片原理类似,是一种逐帧动 ...
随机推荐
- 学习线程池源码--ScheduledThreadPoolExecutor
1. 创建ScheduledThreadPoolExecutor ScheduledThreadPoolExecutor继承自ThreadPoolExecutor,实现了Schedule ...
- web前端学习(三)css学习笔记部分(4)-- CSS选择器详解
4. 元素选择器详解 4.1 元素选择器 4.2 选择器分组 用英文逗号","相连,使用相同的样式表 使用通配符对所有元素进行通用设定. 4.3 类选择器详解 4.3.1. ...
- webpack学习之—— 依赖图(Dependency Graph) 及 构建目标(Targets)
Dependency Graph 任何时候,一个文件依赖于另一个文件,webpack 就把此视为文件之间有依赖关系.这使得 webpack 可以接收非代码资源(non-code asset)(例如图像 ...
- MS17-010远程溢出漏洞 - 永恒之蓝 [CVE-2017-0143]
MS17-010远程溢出漏洞(永恒之蓝) Ti:2019-12-25 By:Mirror王宇阳 MS17-010 CVE-2017-0143 MS17-010 CVE-2017-0144 MS17-0 ...
- 构建PaaS的开源平台:CloudFoundry
CloudFoundry的架构: 点评:这是vmware用ruby开发的一个paas,由于对ruby不太熟悉,还是比较难理解. refer to :http://www.oschina.net/que ...
- Oracle企业管理框架
oracle管理服务器 是一个基于java的web构件,该构件是dba用来监视和控制oracle企业框架内各个受管理目标的实际界面 oracle储存库 已收集到并与受管理目标有关的配置和监视信息被存储 ...
- Leetcode720.Longest Word in Dictionary词典中最长的单词
给出一个字符串数组words组成的一本英语词典.从中找出最长的一个单词,该单词是由words词典中其他单词逐步添加一个字母组成.若其中有多个可行的答案,则返回答案中字典序最小的单词. 若无答案,则返回 ...
- python Web中WSGI uWSGI 以及 uwsgi的区别
WSGI协议 首先弄清下面几个概念: WSGI:全称是Web Server Gateway Interface,WSGI不是服务器,python模块,框架,API或者任何软件,只是一种规范,描述web ...
- 记一次goland的包导入问题
昨天把go的GOPATH环境变量设置成了“/home/mi/app/gopath”,今天用goland新建的项目在/home/mi/go/src目录下,名字是studygolang,如下图. 结果导入 ...
- JavaScript--返回顶部方法:锚链接、行内式js写法、外链式、内嵌式
返回网页顶部方法 一.锚链接 simpleDemo: <!DOCTYPE html> <html lang="en"> <head> <m ...