Android开源中国客户端学习 上拉刷新 底部加载 的listview <4>

原创
2013/06/26 22:01
阅读数 4.9K

这次学习一些osc客户端的 上拉刷新 底部加载 的listview 这里还是以加载新闻为例

 osc上的下拉刷新 和底部自动加载下一页是和qq空间等app相似的,那就学习一下

其实osc是使用了一个开源的控件 --PullToRefreshListView

具体代码恕不粘贴

具体的使用在fragme_news.xml中


<net.oschina.app.widget.PullToRefreshListView
        android:id="@+id/frame_listview_news"
        style="@style/widget_listview" />
在这里说一点,其实osc各个功能的切换只不过是 切换四个fragmelayout的可见性。具体请查看main.xml


先说下拉刷新,其实使用了PullToRefreshListView这个控件后,使用下拉就很简单了 只需监听一个下来事件就ok'


lvNews.setOnRefreshListener(new PullToRefreshListView.OnRefreshListener() {
			public void onRefresh() {
				loadLvNewsData(curNewsCatalog, 0, lvNewsHandler,
						UIHelper.LISTVIEW_ACTION_REFRESH);
			}
		});
只要下拉到一定程度后就可触发这个事件了,然后就loadLvNewsData方法载入数据了,我们再看一下最后一个参数,在调用loadLvNewsData这里就会 isRefresh = true; 



ok 既然isRefresh= true 了 那么不管是否有缓存可读都会从网络读取数据到listview

在news的handler中可能还需要出来上次刷新时间 在获取handler的构造函数handleMessage中:


if (msg.arg1 == UIHelper.LISTVIEW_ACTION_REFRESH) {
					lv.onRefreshComplete(getString(R.string.pull_to_refresh_update)
							+ new Date().toLocaleString());
					lv.setSelection(0);
				} else if (msg.arg1 == UIHelper.LISTVIEW_ACTION_CHANGE_CATALOG) {//是否显示上次什么时候刷新
					lv.onRefreshComplete();
					lv.setSelection(0);
				}


然后是滑动到底部 显示progressbar并加载下一页数据

其实就是控制listview的footview的显示状态:当listview滑动到最底部时,把footview由"更多"改成progressbar 并显示"加载中..."


lvNews.addFooterView(lvNews_footer);// 添加底部视图 必须在setAdapter前 添加FootView

看看底部加载的核心代码:


lvNews.setOnScrollListener(new AbsListView.OnScrollListener() {
			public void onScrollStateChanged(AbsListView view, int scrollState) {
				lvNews.onScrollStateChanged(view, scrollState);

				// 数据为空--不用继续下面代码了
				if (lvNewsData.isEmpty())
					return;

				// 判断是否滚动到底部
				boolean scrollEnd = false;
				try {
					if (view.getPositionForView(lvNews_footer) == view
							.getLastVisiblePosition())// judge if the last view on screen is thelvNews_footer

						scrollEnd = true;
				} catch (Exception e) {
					scrollEnd = false;
				}

				int lvDataState = StringUtils.toInt(lvNews.getTag());
				if (scrollEnd && lvDataState == UIHelper.LISTVIEW_DATA_MORE) {
					lvNews.setTag(UIHelper.LISTVIEW_DATA_LOADING);// prevent repeat load
					lvNews_foot_more.setText(R.string.load_ing);
					lvNews_foot_progress.setVisibility(View.VISIBLE);
					// 当前pageIndex lvNewsSumData: the current count the app has load the news.
					int pageIndex = lvNewsSumData / AppContext.PAGE_SIZE;
					loadLvNewsData(curNewsCatalog, pageIndex, lvNewsHandler,
							UIHelper.LISTVIEW_ACTION_SCROLL);
				}
			}


那么就分析一下

首先判断是否滑动到底部


// 判断是否滚动到底部
				boolean scrollEnd = false;
				try {
					if (view.getPositionForView(lvNews_footer) == view
							.getLastVisiblePosition())// judge if the last view on screen is thelvNews_footer

						scrollEnd = true;
				} catch (Exception e) {
					scrollEnd = false;
				}


感觉用try 块 做判断是否到底部不是什么好方法,会不会很耗费资源?如果是scrollEnd = true


int lvDataState = StringUtils.toInt(lvNews.getTag());
				if (scrollEnd && lvDataState == UIHelper.LISTVIEW_DATA_MORE) {
					lvNews.setTag(UIHelper.LISTVIEW_DATA_LOADING);// prevent repeat load
					lvNews_foot_more.setText(R.string.load_ing);
					lvNews_foot_progress.setVisibility(View.VISIBLE);
					// 当前pageIndex lvNewsSumData: the current count the app has load the news.
					int pageIndex = lvNewsSumData / AppContext.PAGE_SIZE;
					loadLvNewsData(curNewsCatalog, pageIndex, lvNewsHandler,
							UIHelper.LISTVIEW_ACTION_SCROLL);
				}
注意这里有一个


int lvDataState = StringUtils.toInt(lvNews.getTag());和判断lvDataState == UIHelper.LISTVIEW_DATA_MORE这是为了防止重复加载load 数据的.

OK 现在就开始使用loadLvNewsData函数load数据了,那什么时候把progressbar消失呢?当然是在载入完了了数据之后,那么根据第一篇文章我们知道肯定是在handler中处理了

其实实在初始化的时候


lvNewsHandler = this.getLvHandler(lvNews, lvNewsAdapter,
				lvNews_foot_more, lvNews_foot_progress, AppContext.PAGE_SIZE);
这里lvNews_foot_more, lvNews_foot_progress,两个参数就分别是footerview的两个控件了




if (msg.what < pageSize) {
						lv.setTag(UIHelper.LISTVIEW_DATA_FULL);
						adapter.notifyDataSetChanged();
						more.setText(R.string.load_full);
					} else if (msg.what == pageSize) {
						lv.setTag(UIHelper.LISTVIEW_DATA_MORE);
						adapter.notifyDataSetChanged();
						more.setText(R.string.load_more);

						// 特殊处理-热门动弹不能翻页
						if (lv == lvTweet) {
							TweetList tlist = (TweetList) msg.obj;
							if (lvTweetData.size() == tlist.getTweetCount()) {
								lv.setTag(UIHelper.LISTVIEW_DATA_FULL);
								more.setText(R.string.load_full);
							}
						}
					}
progress.setVisibility(ProgressBar.GONE);


展开阅读全文
打赏
4
84 收藏
分享
加载中
SuShine博主

引用来自“troy23”的评论

lvNews.setOnRefreshListener(new PullToRefreshListView.OnRefreshListener() {
public void onRefresh() {
loadLvNewsData(curNewsCatalog, 0, lvNewsHandler,
UIHelper.LISTVIEW_ACTION_REFRESH);
}
}); 如何控制上下滑动index改变呀
谁的index
2014/12/06 16:54
回复
举报
lvNews.setOnRefreshListener(new PullToRefreshListView.OnRefreshListener() {
public void onRefresh() {
loadLvNewsData(curNewsCatalog, 0, lvNewsHandler,
UIHelper.LISTVIEW_ACTION_REFRESH);
}
}); 如何控制上下滑动index改变呀
2014/12/04 22:07
回复
举报

引用来自“SuShine”的评论

引用来自“祝建宾”的评论

引用来自“SuShine”的评论

引用来自“祝建宾”的评论

居然还用上了 try catch 太菜了!

也不能这么说 可能作者有他的意图吧.

刚刚抽空写了篇博客,发表了我自己的一些看法,
http://my.oschina.net/edroid/blog/142598

这个做法 我以前看到过 但是 我记得是有问题的

我现在用的很完美的说
2013/07/05 22:09
回复
举报
SuShine博主

引用来自“祝建宾”的评论

引用来自“SuShine”的评论

引用来自“祝建宾”的评论

居然还用上了 try catch 太菜了!

也不能这么说 可能作者有他的意图吧.

刚刚抽空写了篇博客,发表了我自己的一些看法,
http://my.oschina.net/edroid/blog/142598

这个做法 我以前看到过 但是 我记得是有问题的
2013/07/05 20:03
回复
举报

引用来自“SuShine”的评论

引用来自“祝建宾”的评论

居然还用上了 try catch 太菜了!

也不能这么说 可能作者有他的意图吧.

刚刚抽空写了篇博客,发表了我自己的一些看法,
http://my.oschina.net/edroid/blog/142598
2013/07/04 23:37
回复
举报
都说了开源 看了半天就一个控件……不厚道
2013/07/02 17:18
回复
举报
基本都是对源代码简单说明一下!没劲!

期待楼主更精彩、有独特见解的讲解。
2013/07/01 16:26
回复
举报
SuShine博主

引用来自“祝建宾”的评论

居然还用上了 try catch 太菜了!

也不能这么说 可能作者有他的意图吧.
2013/06/30 19:18
回复
举报
居然还用上了 try catch 太菜了!
2013/06/30 16:21
回复
举报
更多评论
打赏
9 评论
84 收藏
4
分享
返回顶部
顶部