ListView上拉加载更多的UI需求

(1)向上滑动 ListView,当最后一个条目滚入屏幕时开始加载更多条目,在列表底部增加一个 footerView:一个 infinite progressBar,一个 textView 显示 “Loading...”;

(2)根据数据加载的结果更新 view:

(2.1)如果已经没有更多条目,则更新 footerView:仅包含一个 textView 显示“No More”;

(2.2)如果成功获取更多条目,则更新 ListView,同时移除(隐藏) footerView;

(2.3)如果加载失败(网络异常等原因),移除(隐藏) footerView。

综上述,需要有一个 footerView,它包含两种状态:

-------------------------------

| @ Loading... | (借用 @ 当做infinite progressBar)

-------------------------------

-------------------------------

| No More |

-------------------------------

这是一个挺简单 UI 需求,比常见的实现方式少了一种状态:

-------------------------------

| 查看更多 |

-------------------------------

在这种状态下,点击 footerView 也可以和『上拉』一样加载更多条目。我对比了手Q和微信,手Q就多了这个『查看更多』的状态(当然,必须在上拉时恰好让它停在最后一个条目,不然上拉过头后,就立刻变成『Loading...』)。

本需求并不需要这个状态,所以下面的实现分析不会考虑它,所以整体实现相对简单。

为了实现上述需求,需要考虑三个问题:

如何定义 footerView?

何时加载更多?

数据加载完毕后,如何更新视图?

如何定义 footerView?

如上述,footerView 包含两种状态:加载中、没有加载。

『加载中』包含两个控件,infinite progressBar 和 textView,放进一个 LinearLayout;『没有加载』只包含一个控件,textView,也把它放进一个 LinearLayout;然后把这两个 LinearLayout 放到一个 FrameLayout 内。根据状态决定显示哪个 LinearLayout。因此只需要一个 public method:

public class PullUpLoadListViewFooter extends LinearLayout {

public enum State {

LOADING,

NOT_LOADING,

}

public void updateView(State state, String content) {}

}

何时加载更多?

向上滑动 ListView,当最后一个条目滚入屏幕时开始加载更多条目。ListView 可以监听滚动事件,因此知道何时加载更多。但数据加载的工作显然应该交给控制器,也就是 ListView 的托管者比如 Activity 来完成。

所以,在 ListView 中定义一个接口,并在 ListView 滚动事件中回调这个接口方法:

public class PullUpLoadListView extends ListView {

public interface OnPullUpLoadListener {

void onPullUpLoading();

}

public void setOnPullUpLoadListener(OnPullUpLoadListener listener) {

mOnPullUpLoadListener = listener;

}

private OnPullUpLoadListener mOnPullUpLoadListener;

private OnScrollListener mOnScrollListener = new OnScrollListener() {

@Override

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

// Start a new loading when the last item scrolls into screen, instead of overriding method onTouchEvent.

// 检查是否到listView底部,检查callbacks是否注册:

if (needLoad(...)) {

startPullUpLoad();

}

}

};

}

startPullUpLoad() 是listView 处理上拉加载的核心代码:秀出显示『Loading...』的footerView;设置标志位表示『已经处于上拉加载状态中』防止重复加载;回调。

private void startPullUpLoad() {

if (mOnPullUpLoadListener != null) {

// Show the foot view and update its state to LOADING.

showFooterView();

// Set flag

mIsPullUpLoading = true;

// Call the callback to notify the listView's hosted controller to load data.

mOnPullUpLoadListener.onPullUpLoading();

}

}

再由 Activity 实现该接口完成加载工作:

listView.setOnPullUpLoadListener(new PullUpLoadListView.OnPullUpLoadListener() {

@Override

public void onPullUpLoading() {

if (shouldLoadMore) {

// Loading more data

new LoadDataAsyncTask().execute();

} else {

// Already has no more data

// 下面会讲到这个方法

listView.onPullUpLoadFinished(true);

}

}

});

数据加载完毕后,如何更新视图?

ListView 提供一个public方法,根据数据加载的结果更新视图:

public class PullUpLoadListView extends ListView {

// When loading finished, the controller should call this public method to update footer view.

public void onPullUpLoadFinished(boolean hasNoMoreItems) {

// Clear flag

mIsPullUpLoading = false;

if (hasNoMoreItems) {

// when have no more items, update footer view to: NO MORE

mFooterView.updateView(PullUpLoadListViewFooter.State.NOT_LOADING, FOOTER_VIEW_CONTENT_NO_MORE);

} else {

// The other cases: (1)Loading succeed and still has more items, (2)Loading failed,

// should hide footer view.

hideFooterView();

}

}

}

Activity 完成加载数据后,调用 ListView 提供的方法,并更新 adapter 数据集:

listView.onPullUpLoadFinished(false);

// Add more data to adapter and notify data set changed to update listView.

adapter.addMoreItems(newItems);

源码实现总结

(1)数据加载完成后,由PagingListView负责更新adapter,考虑到ListView可能并不清楚adapter的接口,所以还是交给activity比较好;

// PagingListView的实现

public void onFinishLoading(boolean hasMoreItems, List extends Object> {

...

((PagingBaseAdapter) adapter).addMoreItems(newItems);

}

(2)PagingListView维护了一个私有成员boolean hasMoreItems,然后在滚动事件回调onScroll(...)中,如果该值为false,就不会加载更多数据。

我觉得不应该由ListView来维护『是否具有更多的item』,这样会带来一些困惑和额外的工作。比如该值为false的情况下,当外部清空list item后,必须重置 hasMoreItems,否则无法继续加载。

这样逻辑显得比较乱,而『是否可以加载更多』,应该分成两部分:

由 ListView 判断『没有处于加载状态』并且『已经滚到了最后一个条目』则允许加载;

由 Activity 判断『还有更多的数据』则允许加载。

这样就显得清晰很多了。

如下的GIF演示了上拉加载的过程:

android listview自动加载更多,如何实现 Android ListView『上拉加载更多』?相关推荐

  1. java h5 上拉加载更多_移动端H5页面上拉加载更多功能实现(二)

    之前已经写过一篇关于上拉加载更多的文章,那个主要是根据滚动实现分页向后台发起请求实现.这次实现方式为后台返回所有需要加载的数据,前端这边做视觉上的分页效果.实现原理也是根据滚动距离触发加载更多的条件. ...

  2. js上拉加载ajax数据,原生ajax写的上拉加载实例

    上拉加载的思路 1 上拉加载是要把屏幕拉到最底部的时候触发ajax事件请求数据 2.所有要获取屏幕的高度 文档的高度 和滚动的高度 下面的代码是已经做好了兼容的可以直接拿来用 Javascript: ...

  3. H5上拉加载以及在微信内置浏览器上拉加载失效问题记录

    第一次采用了距离顶部距离的方式来控制上拉加载 $(window).scroll(function () {// 滚动条距离顶部的距离 大于 200px时if ($(window).scrollTop( ...

  4. Android ListView 实现下拉刷新上拉加载

    转载请注明出处:http://blog.csdn.net/allen315410/article/details/39965327 1.简介 无疑,在Android开发中,ListView是使用非常频 ...

  5. Android自定义控件实战——实现仿IOS下拉刷新上拉加载 PullToRefreshLayout

    下拉刷新控件,网上有很多版本,有自定义Layout布局的,也有封装控件的,各种实现方式的都有.但是很少有人告诉你具体如何实现的,今天我们就来一步步实现自己封装的 PullToRefreshLayout ...

  6. Jquery 实现H5页面上拉加载更多

    在最新的H5开发项目中,需要开发上拉加载更多的功能,如何实现上拉加载更多,网上有很多插件可以实现,如:mescroll.mui.isScroll等等,最初我也是选择了使用插件,但在使用过程中发现了如果 ...

  7. 手把手教你实现Android RecyclerView上拉加载功能

    心灵鸡汤:知之者不如好之者,好之者不如乐之者. 摘要 一直在用到RecyclerView时都会微微一颤,因为一直都没去了解怎么实现上拉加载,受够了每次去Github找开源引入,因为感觉就为了一个上拉加 ...

  8. 微信小程序 上拉加载更多

    来个上拉刷新,解决一下上拉问题.上拉小伙伴除了用微信小程序自带的onReachBottom外,最多用的就是scroll-view的上拉加载啦.但是呢,scroll-view上拉加载会一到底部就不断的触 ...

  9. 【FastDev4Android框架开发】RecyclerView完全解析之下拉刷新与上拉加载SwipeRefreshLayout(三十一)...

    转载请标明出处: http://blog.csdn.net/developer_jiangqq/article/details/49992269 本文出自:[江清清的博客] (一).前言: [好消息] ...

最新文章

  1. 将远程桌面客户端配置为连接到特定端口
  2. xss_url通关_1-10
  3. 容器网络|深入理解Cilium
  4. 在zabbix中添加监控主机及Items
  5. Pipelines - .NET中的新IO API指引(二)
  6. Qt中QLabel的背景图片设置问题
  7. selenium.common.exceptions.WebDriverException: Message: ‘chromedriver’解决
  8. Java ForkJoin 框架初探
  9. SPH(光滑粒子流体动力学)流体模拟实现二:SPH算法(4)-算法实现2
  10. Matlab处理图像二三例
  11. mysql 未发现数据源名称并且未指定默认驱动程序_SQLSERVER 链接 MYSQL 的 两种方法 及 未发现数据源名称并且未指定默认驱动程序 处理办法...
  12. win7事件查看器事件id_使用免费工具从事件查看器中查找事件ID
  13. 【亲测】服务器事件查看器打不开报错,mmc无法创建管理单元怎么办
  14. jieba——分词、添加词典、词性标注、Tokenize
  15. 前端工程师面试题汇总(我的解析,可能不一定对)(HTML部分)
  16. 【Unity】Jay 开发日志(一)——人物的移动、死亡与平台跳跃
  17. android怎么装windows系统,普通电脑怎么装Windows和安卓的双系统?
  18. 亚马逊运营知识:亚马逊排名规则是怎么样的
  19. 浅谈BIM+智慧工地,拒绝吹嘘,拒绝高大上。
  20. 关于软磁材料开路样品的矫顽力的测量

热门文章

  1. php元素浮动会产生哪些影响,css浮动带来什么问题
  2. 福大计算机课程表,教学文件 - 福州大学电气工程与自动化学院
  3. linux mei swap,Linux swapoff命令
  4. java 自定义注解 生成json_用自定义注解实现fastjson序列化的扩展
  5. linux内核mtd分区,linux-kernel – 在运行时调整MTD分区大小
  6. Win11系统获取管理员权限的方法
  7. 防止重复提交js jquery ajax
  8. Java下载文件的几种方式
  9. Redis缓存那点破事 , 绝杀面试官 25 问
  10. 谈Servlet与JSP