recycleView作為一個新的控件,那是有其特點的。在日常的使用中,基本是可以代替listView和gridview使用的,同時,它還多了一種瀑布流的展示方式。
因此,個人是比較推薦開發者在項目開發過程中逐漸的使用recycview代替listview和gridview的。大家也都知道產品經理的想法永遠是捉摸不定的,這次跟你說要垂直布局,好,等你用listview做完之后,就又跟你說覺得網格布局可能會好一點!!!ok,當你終于把控件轉換成gridview,修改了大量的代碼之后。如果,產品經理再跟你說,最后決定還是使用瀑布流得我樣式好了, 你會不會有種崩潰的感覺。反正,我是會和PM打一架再說的。。。
總而言之,竟然最后還是得從了PM,何不一開始就已經做好準備呢?
RecyclView就是這樣的一款新的控件。它把布局管理,item動畫等都獨立暴露了出來。雖然代碼是增加了,但是卻變得更加的靈活了,像上面的需求你只需要改動一行代碼就可以實現了。
關于RecyView如何使用,網上已經有太多的教程了,因此我也不再講解,大家可以參考下面這位大神的文章:
這是一篇講解的已經很詳細的文章了,感謝作者的分享(還沒有經過您的同意就放上你的文章,請見諒哈)
我這一片文章主要講解的是如何優雅的增加下拉刷新和加載更多
關于下拉刷新
下拉刷新,在網上已經是有很多種的解決方案了,個人是比較喜歡通過在RecyView外層包裹一層 SwipeRefreshLayout來處理的。
SwipeRefreshLayout作為一個新的控件,使用簡單,樣式好看~
1.在xml中使用SwipeRefreshLayout包裹RecycleView
2.綁定控件
refresh_layout= (SwipeRefreshLayout) rootView.findViewById(R.id.refresh_layout);
//添加刷新監聽器
refresh_layout.setOnRefreshListener(newSwipeRefreshLayout.OnRefreshListener() {
? @Override
? public voidonRefresh() {
? //加載數據
? backURL();
}
});
3.在加載完數據之后,記得要在UI線程中調用
if(refresh_layout.isRefreshing()){
? ? refresh_layout.setRefreshing(false);
}
記住這個操作只能在UI線程中執行,而且要是忘記了這個操作,那么即使在加載完數據之后,加載動畫也不會停下來的
關于SwipRefreshLayout的更多用法可以參考
Android開發之SwipeRefreshLayout實現下拉刷新
總體的用法還是非常的簡單易用的。好啦,下拉刷新就是這么的簡單。
這一次的重點來了:
實現加載更多
網上實現加載更多的方法有很多。
今天由于想把項目的體積降下來,要砍掉一些沒有必要的庫,然后我就看到之前為了省時間直接就依賴了一個項目來實現瀑布流,然后瀑布流的布局在整個項目中,其實就只用了一次,就因為只用一次的東西而增加了一個依賴項目,真的是非常的蠢。所有我決定把這個依賴項目砍掉(并不是說這個項目不好)。既然要砍掉它,那就要找到它的替代品,所以我就把目光投向了RecycleView了,使用RecycleView實現瀑布流布局其實還是非常的快的,只要把?
mLayoutManager=newStaggeredGridLayoutManager(2,OrientationHelper.VERTICAL);?
就可以實現了。
關鍵還是在于實現下拉刷新和加載更多。下拉刷新在上面已經講到怎么實現了,下面開始講加載更多
在RecycleView中是沒有onItemClickLinstener,OnItemLongClickListener以及加載更多等等的接口的。這一切都是要是自己實現的。本著不重復造輪子的精神,我先上google了一下。
發現大多是這樣子的
拉刷新和上拉加載更多的RecyclerView,具有下拉和刷新動畫
實現RecyclerView下拉刷新和上拉加載更多以及RecyclerView線性、網格、瀑布流效果演示
What the hell?(并沒有說這樣子的方法不科學,只是可以更簡單的解決)
我只是要簡單的實現加載更多,有必要改動這么多,還要增加footerview,還有對RecycleView增加OnScrollLinstener來監聽是否到達最后一條,還有用 mLayoutManager.findLast...關鍵是瀑布流的layoutmanager還沒有這個接口。。。
于是就開始思考,竟然單擊事件,長按事件可以通過訂閱的方式來實現,那么加載更多是不是也可以?
如果我在初始化Adapter的時候就告訴Adapter:如果到了最后一條數據就告訴我,我來加載更多。
本著這樣的想法,我在Adapter的初始化總增加了這一個參數
ps:在評論中有同學指出如果不滿一屏可能會頻繁觸發loadMoreListener,解決方法就是增加一個 參數 pageNum,用于判斷當前數據滿不滿
publicListAdapter_pic(Context context,List listData,
OnItemClickListener listener,in.yeyeapp.listeners.OnLoadMoreListener loadMoreListener,int pageNum) {
mListener= listener;
mContext= context.getApplicationContext();
this.mInflater= LayoutInflater.from(mContext);
this.data= listData;
this.pageNum = pageNum;
//訂閱加載更多
this.loadMoreListener= loadMoreListener;
}
實現加載更多的具體做法
mAdapter=newListAdapter_pic(getActivity(),mListAlbums,(OnItemClickListener)this, newOnLoadMoreListener() {
@Override
public voidonLoadMore() {
currentPage++;
nextPage();
}
});
OnLoadMore的具體實現
public interfaceOnLoadMoreListener {
public voidonLoadMore();
}
接下來是在合適的時候觸發事件。
仔細閱讀Adapter的代碼我們會發現 onBindViewHolder 是負責繪制ItemView的函數,所以它是知道它當前已經畫到第一幾個Item了,所以這項重任就交給它了
@Override
public voidonBindViewHolder(ViewHolder holder, intposition) {
//新增對 loadMoreListener 的非空判斷,以及對數據數目滿屏的判斷,防止觸發空指針錯誤及數據不滿而頻繁觸發加載更多
if(position == getItemCount() -1 && loadMoreListener != null && getCount() > pageNum) {
//告訴訂閱者已經到最后一個了,可以加載更多了
loadMoreListener.onLoadMore();
}
//其他綁定資源的操作
。。。
}
這樣,加載更多就大功告成了!!!
基本在網絡良好的情況下,是可以無感的加載更多的
做法也是比較的簡單
核心的思想就是讓Adapter在繪制到最后一個view的時候告訴主線程說可以更新了。。。
如果想讓加載更多更快一步執行,可以通過修改判斷的條件
if(position == getItemCount() -1)
可以在倒數第二個,倒數第三個等就可以加載更多,這樣可以讓用戶更加感知不到加載的過程
不過就要注意數據的個數了