1. 动画功能的基本实现
首先我们梳理一下需求
- 界面上有三个元素,一个开启动画按钮start,一个关闭动画按钮end,一个ListView展示数据
- ListView默认是GONE的
- 点击开启动画按钮前,需要先将ListView置为VISIBLE,然后再开启动画。开启之后默认展示第一项。
- 点击关闭动画按钮后,在动画执行结束后,将ListView置为GONE。
- 点击ListView的Item后,也执行第4步骤的关闭动画操作。
我们知道,ViewGroup的动画需要LayoutAnimationController来支持,那么ListView继承于ViewGroup,当然也是通过LayoutAnimationController来实现Item的动画。这里需要注意的是,怎么拿到ListView最后一项Item的动画结束后的监听回调呢?代码如下:
/**
* Created by chenchen on 2016/11/25.
*/
public class ListViewAnimationListener implements Animation.AnimationListener {
private int count = 0;
private ListView listView;
private OnAnimationFinishListener listener;
public ListViewAnimationListener(ListView listView, OnAnimationFinishListener listener) {
this.listView = listView;
this.listener = listener;
}
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
// 没有子控件,则直接完成
if(listView.getChildCount() == 0){
if(listener != null){
listener.onFinish();
}
}else{
count++;
if(count == listView.getChildCount() && listener != null){
listener.onFinish();
reset();
}
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
public void reset(){
count = 0;
}
public interface OnAnimationFinishListener{
void onFinish();
}
}
代码很少,可以看出具体的逻辑是:每次动画结束时使变量count自增,当count等于listView的getChildCount()时,我们认为所有的Item的动画结束了。至于为什么是getChildCount()而不是adapter的getCount()呢?我们知道ListView的缓存原理,内存中始终只有屏幕可见个Item,因此动画是实际作用于真实存在内存中的Item。
好了,接下来贴出全部代码,其他部分就很简单了。
首先是两个动画文件:
<!-- translate_in -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="-100%p" android:toXDelta="0%p"
android:duration="100"/>
</set>
<!-- translate_out -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0%p" android:toXDelta="-100%p"
android:duration="100" />
</set>
然后是ListView的item文件,很简单
<?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="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/txt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="@android:color/black"
android:textSize="15sp" />
</LinearLayout>
然后是activity_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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal"
android:paddingLeft="20dp"
android:paddingRight="20dp"
>
<Button
android:id="@+id/start"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:gravity="center"
android:text="开启列表动画"
android:textSize="18sp"
android:textColor="#333333"
/>
<Button
android:id="@+id/end"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_marginLeft="20dp"
android:gravity="center"
android:text="关闭列表动画"
android:textSize="18sp"
android:textColor="#333333"
/>
</LinearLayout>
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:cacheColorHint="@android:color/transparent"