最近有朋友展示了一种效果,就是ListView在滑动的过程中新加入的item会有一个从底部滑入的效果,我感觉这种效果还算不错,就去想了想拿到我身上应该怎么去实现这种效果,在试过几种方案后,最后选择了一种使用起来还算比较简单的方式拿出来分享一下。
在开始分享之前,先来看看我们需要做成什么效果吧,

恩,看到什么效果了吗?仔细看滑动过程中的底部,新加入的item会以一种动画的形式加入,马上,我们就来实现这种效果!

实现方式的选择

当我第一次看到这种效果的时候,我首先想到的是LayoutAnimation,不过很快就让我否决了,为什么呢?我们能的动画只是在新加入的item的起到效果,而其他的item是没有这个效果的,这种方式用LayoutAnimation是做不到的, 那我们应该怎么实现呢?关键点就在动画在什么时候有效!前面我们说过很多次了,

新加入的item会以一种动画的形式加入

我们只要抓住这一点往下想,很快就能想到AdaptergetView上,在新item加入的时候,Adapter的getView必定是去执行的,我们沿着这个思路往下走,很快我们又遇到问题了,

我们怎么判断已经滑动到底部了?

很多人会不假思索的回答,这个问题容易! 这不和ListView的分页一样吗!当然不是了, ListView分页的底部是判断的数据集的最后一项,不太适用我们这里,而且纵观ListView的几个方法,我们并没有找到合适的方法去使用,所以,我们只能自己去判断了,怎么判断?还是在监听的OnScrollListener里,在这里面判断是不是往下滑动的,至于是不是到达底部了,交给getView去做!所以我们还需要在Adapter中知道ListView的存在,并给他设置滑动监听。

假设,现在我们已经可以可以判断滑动到底部了,我们用一个状态变量isScrollDown来表示,那是不是现在我们就可以在 getView里通过isScrollDown来判断是否给convertView一个动画呢?

基本的实现思路已经阐述完了,下面我们就来着手用代码来实现我们的思路,我们需要解决以下问题,

  1. 尽量将这些代码封装好,以避免每次使用的时候都copy一遍代码
  2. 具体用代码怎么判断ListView往下滑动

对于第一个问题,我们采用大多数情况下使用的方式,就是:

自定义一个抽象的Adapter,实现BaseAdapter中的getView方法,并定义一个buildView
来代替getView的功能。

这样做的好处就是,我们可以在getView中做我们想做的事,而不必在意convertView怎么形成。这也非常符合我们的需求,所以代码可以这么写,

public abstract class BaseFlyAdapter extends BaseAdapter {public View getView(int position, View convertView, ViewGroup parent) {View view = buildView(position, convertView, parent);return view;}public abstract View buildView(int position, View convertView, ViewGroup parent);
}

上面说了,我们需要监听ListView的滑动,这里我们在BaseFlyAdapter中也一块搞定!那我们的BaseFlyAdapter还需要一个ListView,并给他设置OnScrollListener

public abstract class BaseFlyAdapter extends BaseAdapter {private ListView mListView;public void bindView(ListView listView) {mListView = listView;mListView.setOnScrollListener(mScrollListener);}private OnScrollListener mScrollListener = new OnScrollListener() {public void onScrollStateChanged(AbsListView view, int scrollState) {}public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {}};...
}

准备好了这些,我们就来实现如果判断往下滑动这个需求,先上代码,

public abstract class BaseFlyAdapter extends BaseAdapter {  private ListView mListView;private boolean isScrollDown; // 是否往下滑动private int mFirstPosition; // 第一个可见item的位置private int mFirstTop; // 第一个可以item的top值public void bindView(ListView listView) {mListView = listView;mListView.setOnScrollListener(mScrollListener);}private OnScrollListener mScrollListener = new OnScrollListener() {public void onScrollStateChanged(AbsListView view, int scrollState) {if(scrollState == OnScrollListener.SCROLL_STATE_IDLE) isScrollDown = false;}public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {View firstChild = view.getChildAt(0);if(firstChild == null) return;int top = firstChild.getTop();isScrollDown = firstVisibleItem > mFirstPosition || mFirstTop > top;mFirstTop = top;mFirstPosition = firstVisibleItem;}};
}

具体的代码都是mScrollListener中,首先来看看onScrollStateChanged,这里面的代码很简单,就是在滑动停止的时候去恢复isScrollDown变量。最重要的代码还是在onScroll中。下面我们来具体看看这里面的实现。

首先我们获取ListView的第一个view——firstChild,如果这里你不明白怎么回事的话,可以去看看ListView的复用机制,接着我们来获取到firstChild的top值,这些都是为下面去判断是不是往下滑动做准备的,那怎么判断呢?

isScrollDown = firstVisibleItem > mFirstPosition || mFirstTop > top;

一个的操作,这里要考虑两种情况,

  1. 新的item加入的时候,第一个item已经滑动出屏幕外。
  2. 当新的item加入,但第一个item还没滑动出屏幕外。

对于第一种情况,是常规的一种情况,我们直接通过判断第一个可见项,注意这里的第一个可见项是指在我们数据集中的,并且判断是不是大于我们之前保存的firstVisibleItem就ok, 可以看一下最后面的代码,我们去保存了firstVisibleItem和第一个View的top值。对于第二种情况,我们只需要判断View的top值是不是大于我们最后一次保存的值就ok。

ok,到现在为止,我们可以知道ListView是不是往下滑动了,下面就开始给新加入的item添加动画吧。为了灵活,我们将动画的定义放到外部,所以我们还需要给BaseFlyAdapter一个方法去设置动画,

public abstract class BaseFlyAdapter extends BaseAdapter {private AnimationSet mAnimationSet;...public void setAnimation(AnimationSet set) {mAnimationSet = set;}...
}

动画设置好了,我们最后就来看看在getView中怎么做吧。上面说了,动画的执行是在getView中,

public abstract class BaseFlyAdapter extends BaseAdapter {...public View getView(int position, View convertView, ViewGroup parent) {View view = buildView(position, convertView, parent);if(isScrollDown && mAnimationSet != null) {cancelAnimation();view.startAnimation(mAnimationSet);}return view;}private void cancelAnimation() {int count = mListView.getChildCount();for(int i=0;i<count;i++) {mListView.getChildAt(i).clearAnimation();}}
}

首先调用buildView,以前我们在getView中写的代码,现在需要放到buildView中了,然后我们去判断现在是不是往下滑动,如果是往下滑动,首先cancel掉所有item的动画,这样做的目的是防止在某个瞬间多个item执行动画,然后直接调用convertView.startAnimation来开始动画。不过,还记得我们在上面的一句话吗?

至于是不是到达底部了,交给getView去做!

我们看getView的代码里也没有关于解决这个问题的代码啊!对,这没有错,getView执行了,那肯定是新的item加入了,而且我们在getView中做了是不是往下滑动的判断了,所以这个问题自然就解决了!

ok,ok, 万事俱备了,下面就让我们开始使用一下吧,

public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);final ListView listView = (ListView) findViewById(R.id.list);MyAdapter adapter = new MyAdapter();adapter.bindView(listView);adapter.setAnimation((AnimationSet) AnimationUtils.loadAnimation(this, R.anim.anim));listView.setAdapter(adapter);}
}

先去无视MyAdapter的代码, 它肯定是继承了我们定义的BaseFlyAdapter, 我们通过setAnimation来设置了一个动画,我们先来看看这个动画怎么写的吧,

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" ><translate
        android:duration="500"android:fromYDelta="50%"android:toYDelta="0" />
</set>

不多说,一个简单的translate动画。
最后,我们再来看看MyAdapter吧,其实和我们继承BaseAdapter一样只不过我们不需要书写getView的代码,而是放到buildView中,

class MyAdapter extends BaseFlyAdapter {public int getCount() {return 100;}public Object getItem(int position) {return "hello";}public long getItemId(int position) {return position;}@Overridepublic View buildView(int position, View convertView, ViewGroup parent) {if(convertView == null) {convertView = View.inflate(parent.getContext(), R.layout.item, null);}return convertView;}
}

好了,到现在你可以看一下效果啦,当然这里我们把动画的定义抽出来了,这样做的好处就是可以随意切换动画,现在我们修改动画为alpha动画,

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" ><alpha
        android:duration="500"android:fillAfter="true"android:fromAlpha="0.0"android:toAlpha="1.0"/>
</set>

而我们的代码不需要改变,再来看看效果,

很轻松,一个alpha的效果就完成了。就到这里吧。

代码下载,戳这里

ListView底部item飞入动画效果相关推荐

  1. Android—ListView Item 展开动画效果

    Android-ListView Item 展开动画效果 最近在做一个关于ListView item的展开效果,类似于 "粮仓" App 的商店页面,点击Item,展开显示子Vie ...

  2. html中购物车小球飞入的效果,vue项目中css3实现加入购物车小球抛物线飞入动画效果...

    学习Vue中在做移动端商城练习项目时,记录css3实现加入购物车抛物线小球飞入动画效果.下面会介绍我在项目中实现抛物运动的简单方法. 知识点:css3动画(抛物线运动).vue动态绑定事件(控制小球出 ...

  3. 高仿 自如APP 底部导航切换动画效果

    code小生 一个专注大前端领域的技术平台公众号回复Android加入安卓技术群 作者:孔鹏飞 链接:https://www.jianshu.com/p/7a544cf34bcf 声明:本文已获孔鹏飞 ...

  4. jquery mysql实现加入购物车_jQuery实现加入购物车飞入动画效果

    HTML 首先载入jQuery库文件和jquery.fly.min.js插件. 接着,将商品信息html结构布置好,本例中,我们用四个商品并排布置,每个商品box中包括有商品图片.价格.名称以及加入购 ...

  5. android从底部弹出动画效果,七星电子游戏 -七星电子游戏V8.5.51

    一.Keepalived 1.目录 导言 查找结点的效率如何提升? 什么是跳跃表? 跳跃表必须是完美的? 预备知识 抛硬币实验 模拟建表 操作解析 伪代码 代码实现 柔性数组 跳跃表的创建与销毁 跳跃 ...

  6. Android之设置ListView数据显示的动画效果

    效果图: 平时我们要实现ListView数据显示时的动画效果,可以使用LayoutAnimationController为ListView设置动画效果,并通过ListView的setLayoutAni ...

  7. css 右上角 翻开动画_27个精致的CSS3动画效果源代码下载

    CSS主要用于控制网页的外观,CSS代码可以随意变化网页的布局和网页的内容样式.当CSS3出现以后,更是可以让网页增添了不少动画元素,随着IE6,7的淘汰,手机端的崛起更是让它成熟了许多.CSS3动画 ...

  8. RecyclerView.ItemAnimator实现动画效果

    Item动画来源 在RecyclerView的源码中,有一个ItemHolderInfo.java.其源码如下: ItemHolderInfo主要是用来表示RecyclerView中item的信息. ...

  9. Android中的popupwindow从底部进入和退出的动画效果

    今天,简单讲讲android使用popupwindow时设置popupwindow进入和退出的动画效果. 其实这个很简单,之前设置popupwindow从底部进入和退出的效果时,当时记不清了,所以在网 ...

最新文章

  1. 本地 无法启动 SQL Server 错误代码126
  2. ladp3 获取属性_Ldap获取ad属性的方法.
  3. 【学习笔记】28、类的方法及参数介绍
  4. 程序员刚结婚3天,老婆疑似骗婚?聊天记录曝光,网友:拜金实锤
  5. Windows 11 预览版 Build 22000.168 发布
  6. jquery如何阻止子元素继承父元素的事件(又称事件冒泡)
  7. 一建机电实务教材电子版_20年一建其实并不难,官方出版:复习题集(精修),速做速提90分...
  8. 重装linux之后gcc等下载不了,Redhat linux下安装gcc
  9. var let this的区别
  10. 大庆中学2021年高考成绩查询,黑龙江大庆最好的5所高中,对比2020年高考成绩,谁的实力更强?...
  11. 算法高级(1)-概述
  12. C语言IDE和编辑器比较
  13. 机器学习:心血管疾病数据分析
  14. vscode快速删除空白行方法
  15. 对游戏编程开发的一点思考
  16. [导入]陈冠希蛰伏35天后闪电复出 将与舒淇演爱情片
  17. 基于SSM的培训班管理系统
  18. SEM竞价员一天的工作流程了解一下?
  19. 数据结构——栈和队列
  20. 【JAVA】Java 内存模型中的 happen-before

热门文章

  1. 城际快车 /城际拼车 /定制客运 /城际包车 运营系统源码平台
  2. 与建行进行善付通支付接口小知识
  3. 用c语言星号输出c字母,C语言格式化输出中的星号
  4. Python 彩色图转换成素描图(灰度图)
  5. 《PR基础教程入门篇-学习笔记》-009
  6. 40个值得收藏的学习网站合集
  7. 广告防火墙(Android),天行广告防火墙
  8. 微信在线订票小程序源码开发功能说明
  9. 太极root权限_太极app下载-太极(免root)最新版本下载安装v5.7.0
  10. 学习日记:2022年2月15日