博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 动态加载 ListView 实现
阅读量:6705 次
发布时间:2019-06-25

本文共 6671 字,大约阅读时间需要 22 分钟。

  hot3.png

首先讲原理:

ListView 可以设置一个滚动监听器

android.widget.AbsListView.setOnScrollListener(OnScrollListener l)
有个方法

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
这里面有三个参数:
firstVisibleItem:
第一个可见Item在所有Item中的位置(即屏幕上显示的第一行,在你的数据数组中的位置)
visibleItemCount:
可见Item个数(屏幕内可以显示多少行)
totalItemCount:
总共有多少行数据
通过这个3个参数容易想到,如果 
firstVisibleItem + 
visibleItemCount >= 
totalItemCount 不就表明 列表已经滑到了底部么?这个时候就是我们加载数据的时机了!

然后我们需要在列表底部增加一个 item 显示:点击加载更多 或者 正在加载中请稍后 或者 没有更多数据了

这个我们要用到

ListView.addFooterView(View v)

添加了 footView ,footView 就成了列表最后一行,也就说相对于你的总数据增加了一行,所有这里有一点要注意的地方:

调用这个方法必须在 ListView.SetAdapter() 之前,否则将会影响 Cursor 类适配器

知道了原理就很简单了,下面奉上我封装的 LoaderListView

/** * 下拉自动加载的 Listview  *  * @author Yichou * @创建日期 2013-3-19 16:01:10 *  * 2013-6-30 */public class LoaderListView extends ListView implements 		OnScrollListener, 		OnItemClickListener,		OnClickListener {	public interface LoadNotifyer {		public void load();	}		public interface OnScrollStateChangedListener {		public void onScrollStateChanged(int oldState, int newState);	}		private LinearLayout footViewLoading, footViewRetry, footViewNomore;	private LoadNotifyer loadNotifyer;	private int scrollState;	private OnScrollStateChangedListener onScrollStateChangedListener;		public LoaderListView(Context context, AttributeSet attrs, int defStyle) {		super(context, attrs, defStyle);		init(context);	}	public LoaderListView(Context context, AttributeSet attrs) {		super(context, attrs);		init(context);	}	public LoaderListView(Context context) {		super(context);		init(context);	}		@Override	public void onClick(View v) {		if(v.getId() == 0x1001){ //重新加载			setFootviewType(FOOTVIEW_TYPE.LOADING);			if(loadNotifyer != null)				loadNotifyer.load();		}else if (v.getId() == 0x1002) {			setSelection(0);		}	}		private void init(Context context) {		footViewLoading = new LinearLayout(context);		footViewLoading.setOrientation(LinearLayout.HORIZONTAL);		footViewLoading.setGravity(Gravity.CENTER);		ProgressBar bar = new ProgressBar(context);		TextView textView = new TextView(context);		textView.setText("加载中...");		footViewLoading.addView(bar, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));		footViewLoading.addView(textView, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));				footViewRetry = new LinearLayout(context);		footViewRetry.setOrientation(LinearLayout.HORIZONTAL);		footViewRetry.setGravity(Gravity.CENTER);		textView = new TextView(context);		textView.setId(0x1001);		textView.setGravity(Gravity.CENTER);		textView.setText("网络不给力,请重试 o(︶︿︶)o");		textView.setOnClickListener(this);		footViewRetry.addView(textView, new LayoutParams(LayoutParams.WRAP_CONTENT, getFixPx(50)));				footViewNomore = new LinearLayout(context);		footViewNomore.setOrientation(LinearLayout.HORIZONTAL);		footViewNomore.setGravity(Gravity.CENTER);		footViewNomore.setId(0x1002);		textView = new TextView(context);		textView.setText("返回顶部↑");		textView.setGravity(Gravity.CENTER);				footViewNomore.setClickable(true);		footViewNomore.setOnClickListener(this);		footViewNomore.addView(textView, new LayoutParams(LayoutParams.WRAP_CONTENT, getFixPx(50)));				setFootviewType(FOOTVIEW_TYPE.LOADING);				setOnScrollListener(this);		scrollState = SCROLL_STATE_IDLE;				super.setOnItemClickListener(this);	}		public enum FOOTVIEW_TYPE {		/** 加载中 */		LOADING, 		/** 没有更多了,返回顶部 */		NOMOR, 		/** 加载失败重试 */		RETRY,		/**无*/		NONE	}		private View curFootView;	public void setFootviewType(FOOTVIEW_TYPE type) {		if(curFootView != null && curFootView.getTag() == type)			return;				if(curFootView != null)			removeFooterView(curFootView);				switch (type) {		case LOADING:			curFootView = footViewLoading;			break;		case NOMOR:			curFootView = footViewNomore;			break;		case RETRY:			curFootView = footViewRetry;			break;		case NONE:			return;		}				addFooterView(curFootView);		curFootView.setTag(type);	}	private View curHeadView;	public void setHeadView(View v) {		if(curHeadView!=null)			return;		curHeadView=v;		addHeaderView(v);	}		@Override	public void onScrollStateChanged(AbsListView view, int scrollState) {		if (scrollState != this.scrollState) {			if(onScrollStateChangedListener != null){				onScrollStateChangedListener.onScrollStateChanged(this.scrollState, scrollState);			}			this.scrollState = scrollState;		}	}	protected int firstVisibleItem, visibleItemCount, totalItemCount;		@Override	public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {		if(totalItemCount < 2 ) //footview 也算			return;		//		System.out.println("first=" + firstVisibleItem + ",visible=" + visibleItemCount + ",total=" + totalItemCount);				if(firstVisibleItem + visibleItemCount >= totalItemCount){ //说明 footView 可见,通知加载更多			if (loadNotifyer != null && (curFootView != footViewNomore)) {				loadNotifyer.load();			}		}		this.firstVisibleItem = firstVisibleItem;		this.visibleItemCount = visibleItemCount;		this.totalItemCount = totalItemCount;	}		public int getFirstVisibleItem() {		return firstVisibleItem;	}		public int getVisibleItemCount() {		return visibleItemCount;	}		public int getScrollState() {		return scrollState;	}		public void setLoadNotifyer(LoadNotifyer loadNotifyer) {		this.loadNotifyer = loadNotifyer;	}		public void setOnScrollStateChangedListener(OnScrollStateChangedListener onScrollStateChangedListener) {		this.onScrollStateChangedListener = onScrollStateChangedListener;	}		public int getFixPx(int dp){		float scale=getContext().getResources().getDisplayMetrics().density;		return (int)(scale*dp+0.5);	}	private OnItemClickListener listener;	@Override	public void setOnItemClickListener(OnItemClickListener listener) {		this.listener = listener;//		super.setOnItemClickListener(listener);	}		@Override	public void onItemClick(AdapterView
parent, View view, int position, long id) { if(listener==null)return; if(curHeadView != null){ if(position==0)return; listener.onItemClick(parent, view, position-1, id); }else{ listener.onItemClick(parent, view, position, id); } }}

使用很方便,只需调用

LoaderListView.setLoadNotifyer(LoadNotifyer loadNotifyer)
然后每次滑到底部需要加载更多数据的时候,就会回调 
LoadNotifyer.load()
然后你在 load() 方法里加载下一页数据,加载完毕调用 
Adapter.notifyDataSetChanged()
列表就展示新数据了!

此外我这里面还封装了一个神奇的功能是设置 FootView 状态:

这里有四种状态:

public enum FOOTVIEW_TYPE {		/** 加载中 */		LOADING, 		/** 没有更多了,返回顶部 */		NOMOR, 		/** 加载失败重试 */		RETRY,		/**无*/		NONE	}
在加载下一页失败的时候,调用
listView.setFootviewType(FOOTVIEW_TYPE.RETRY)
列表底部显示改为,加载失败,点击重试,用户点击之后,会再次回调你的 load() 方法

同理

当你没有更多数据的时候调用
listView.setFootviewType(FOOTVIEW_TYPE.NOMOR)
列表底部显示改为 回到顶部 用户点击后自动跳到第一行!

嗯,很好!很强大!必须就顶一个!欢迎拍砖!

转载于:https://my.oschina.net/edroid/blog/142598

你可能感兴趣的文章
Android杂谈--Activity、Window、View的关系
查看>>
使用delphi 开发多层应用(十)安全访问服务器
查看>>
JavaScript计算字符串中每个字符出现的次数
查看>>
mvc中的ViewData用到webfrom中去
查看>>
小白学数据分析------>描述性统计术语汇总
查看>>
STL的常用算法
查看>>
[转载]java.lang.OutOfMemoryError: bitmap size exceeds VM budget解决方法
查看>>
SKY IM-A800S 驱动下载
查看>>
应用程序 数据缓存
查看>>
TFS签入签出
查看>>
第二条:遇到多个构造器参数(Constructor Parameters)时要考虑用构建器(Builder)
查看>>
成长,没你想象的那么迫切
查看>>
ASP.NET Core 中文文档 第一章 入门
查看>>
jQuery入门(2)使用jQuery操作元素的属性与样式
查看>>
贴片电阻分类、阻值、功率、封装、尺寸
查看>>
scala+hadoop+spark环境搭建
查看>>
Mqtt协议IOS端移植2
查看>>
Stitching模块中leaveBiggestComponent初步研究
查看>>
使用PrintWriter out=response.getWriter();输出script脚本时乱码解决
查看>>
X.509证书及CeritificationPath及PKCS
查看>>