Android ListView下拉刷新

ListView是我们经常用来展示数据的一个控件,但是由于我们手机的性能和流量的问题,往往我们从服务器中取数据,不能一次性将数据取出来,比如一个新闻的手机APP,每天的新闻是非常多的,单论传输数据的流量就是一个天文数字,所以我们要经常实现类似下拉刷新的功能。

  • 首先加载数据的时候先加载一小部分
  • 每次当滚动到最后的时候,进行一次自动刷新或者是让用户选择刷新

效果图

实现

  1. 为了方便我们以后重复使用该ListView我么需要做一些封装,新建一个类来继承我们ListView类
  2. 下方的进图条是我们的ListView的footerView
  3. 封装一个接口,当给我们的listview到最后的时候,调用该回调函数,进行更新数据,并将我们的进度条隐藏

主要代码

ListView代码

package com.example.it.studypulltoreference;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.ProgressBar; /*
* 具有下拉刷新的listView
* */
public class PullToRefreshListView extends ListView implements AbsListView.OnScrollListener { private View footerView;// FooterView ListView的页脚 private ProgressBar pbRefresh;// footerView中的 进图条控件 private int currentItemCount; //表示当前已经存在的Item的数量 private int totalCount; //全部Item的数量 private OnLoad onLoad; //加载数据时执行的事件 //region 构造函数
public PullToRefreshListView(Context context) {
super(context);
init();
} public PullToRefreshListView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
} public PullToRefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
} public PullToRefreshListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
//endregion //初始化方法
private void init() {
LayoutInflater inflater = LayoutInflater.from(this.getContext());
footerView = inflater.inflate(R.layout.footerview_refresh, null);
pbRefresh = (ProgressBar) footerView.findViewById(R.id.pbRefresh);
pbRefresh.setVisibility(GONE); //为ListView添加页脚
this.addFooterView(footerView); this.setOnScrollListener(this);
} /*
* 回调方法:当ListView或者GridVie被滑动的时候在下一帧动滑动动画渲染完成之前调用此方法
* */
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
/*
* 如果当前的所存在的Item的数量已经是等于全部的Item的数量的那么
* 我们需要进行自动刷新数据
* */
//已经滑动到底部,并且用户没有进行滑动操作时刷新数据
if (currentItemCount == totalCount && scrollState == SCROLL_STATE_IDLE) {
this.pbRefresh.setVisibility(VISIBLE);
//执行刷新操作
this.onLoad.loadData(this.currentItemCount, this.pbRefresh);
}
} /*
* 回调方法:当list 或者 grid 正在被滑动的时候调用,调用在滑动完成之前
* view 报告滚动状态的View
* firstVisibleItem:第一个可见的Item的索引,如果当前没有可见的Cells 那么为0
* visibleItemCount 当前可见列的数量
* totalItemCount Adapter 数据项的数量
* */
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
//在滚动事件中不断的更新 已经存在的Item的数量
currentItemCount = firstVisibleItem + visibleItemCount; totalCount = totalItemCount;
} //为onLoad赋值
public void setOnLoad(OnLoad onLoad) {
this.onLoad = onLoad;
} /*
* 回调函数的接口
* */
public interface OnLoad {
void loadData(int beginIndex, ProgressBar pb);
} }

调用代码

package com.example.it.studypulltoreference;

import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ProgressBar; import java.util.ArrayList;
import java.util.List; public class HomeActivity extends AppCompatActivity implements PullToRefreshListView.OnLoad { private int stepCount = 30;//每次刷新加载的内容的数量
private List<String> stringList = new ArrayList<String>();
private DataAdapter adapter;
private PullToRefreshListView listView; /*
* 初始化一些模拟的数据
* */
private void initData() {
for (int i = 0; i < 200; i++) {
stringList.add("程序猿" + (i + 1));
}
}
//初始化ListView
private void init() {
adapter = new DataAdapter(this, new ArrayList<String>());
this.listView.setAdapter(adapter);
} @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home); listView = (PullToRefreshListView) this.findViewById(R.id.lvData); init(); initData(); //设置刷新数据的方法
listView.setOnLoad(this); loadData(0, null);
} /*
* 想Adapter中的数据源填充数据
* */
@Override
public void loadData(final int beginIndex, final ProgressBar pb) {
new Thread(new Runnable() {
@Override
public void run() {
//如果pb不为null不是初始化数据
if (pb != null) {
//模拟加载中 睡眠 2秒
SystemClock.sleep(2000l);
} for (int i = beginIndex; i < beginIndex + stepCount; i++) {
if (i < stringList.size())
adapter.addItem(stringList.get(i));
}
//加载数据完成回更新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
if (pb != null)
pb.setVisibility(View.GONE);
//刷新Adapter
adapter.notifyDataSetChanged();
}
}); }
}).start();
}
}

源码下载

http://git.oschina.net/ShareKnowledge/pull_to_reference

最新文章

  1. SQL Server窗口函数:ROWS与RANGE
  2. linux sudo apt-get用法详解
  3. IOS应用程序生命周期
  4. poj 1915 http://poj.org/problem?id=1915
  5. C#-datagridview隐藏行头
  6. 2014年到期的myeclipse5.5.1注冊码
  7. 【2】JAVA---地址App小软件(ListPanel.class)(表现层)
  8. linux 虚拟机下配置tomcat
  9. iOS 数据库操作(使用FMDB)
  10. C++中的函数指针用法
  11. LFS,编译自己的Linux系统 - 准备分区
  12. 初学DIV+CSS要记住的
  13. mysql数据库字段区分大小写的设置方法
  14. Swift - 程序进入后台,以及应用终止时调用的方法
  15. angular-bootstrap ui-date组件问题总结
  16. 导入sass文件
  17. Android预置Apk方法
  18. [转]MySQL常用Json函数和MySQL常用字符串函数
  19. Modbus库开发笔记之一:实现功能的基本设计
  20. 【vim】缩写 :ab [缩写] [要替换的文字]

热门文章

  1. C# IsAssignableFrom与IsSubClassOf 判断匿名类是否继承父类
  2. 記一次undo問題
  3. 使用idea的的第一个坑-----javax.xml.ws.WebServiceRef
  4. ClientDataset 三层 var and out arguments must match parameter
  5. NLP里面好的学习资料
  6. 2.SpringBoot之返回json数据
  7. elasticsearch文档学习
  8. SQL存储过程相关信息查看
  9. R语言学习笔记:choose、factorial、combn排列组合函数
  10. C# 图片和二进制之间的转换