此次学习一些osc客户端的 上拉刷新 底部加载 的listview 这里仍是以加载新闻为例 php
osc上的下拉刷新 和底部自动加载下一页是和qq空间等app类似的,那就学习一下 java
其实osc是使用了一个开源的控件 --PullToRefreshListView android
具体代码恕不粘贴 缓存
具体的使用在fragme_news.xml中 网络
<net.oschina.app.widget.PullToRefreshListView android:id="@+id/frame_listview_news" style="@style/widget_listview" />在这里说一点,其实osc各个功能的切换只不过是 切换四个fragmelayout的可见性。具体请查看main.xml
先说下拉刷新,其实使用了PullToRefreshListView这个控件后,使用下拉就很简单了 只需监听一个下来事件就ok' app
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并加载下一页数据 this
其实就是控制listview的footview的显示状态:当listview滑动到最底部时,把footview由"更多"改为progressbar 并显示"加载中..." spa
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);