此次學習一些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);