首先介紹下RecyclerView扣孟,RecyclerView相比ListView增加了很多新特性:
? Adapter中的ViewHolder模式 - 對于ListView來說隘冲,通過創(chuàng)建ViewHolder來提升性能并不是必須的翘鸭。因為ListView并沒有嚴(yán)格的ViewHolder設(shè)計模式臼勉。但是在使用RecyclerView的時候,Adapter必須實現(xiàn)至少一個ViewHolder,必須遵循ViewHolder設(shè)計模式胃榕。
? 定制Item條目 - ListView只能實現(xiàn)垂直線性排列的列表視圖,與之不同的是瞄摊,RecyclerView可以通過設(shè)置RecyclerView.LayoutManager來定制不同風(fēng)格的視圖勋又,比如水平滾動列表或者不規(guī)則的瀑布流列表。
? Item動畫 - 在ListView中沒有提供任何方法或者接口换帜,方便開發(fā)者實現(xiàn)Item的增刪動畫楔壤。相反地,可以通過設(shè)置RecyclerView的RecyclerView.ItemAnimator來為條目增加動畫效果惯驼。
? 設(shè)置數(shù)據(jù)源 - 在LisView中針對不同數(shù)據(jù)封裝了各種類型的Adapter蹲嚣,比如用來處理數(shù)組的ArrayAdapter和用來展示Database結(jié)果的CursorAdapter递瑰。相反地,在RecyclerView中必須自定義實現(xiàn)RecyclerView.Adapter并為其提供數(shù)據(jù)集合端铛。
? 設(shè)置條目分割線 - 在ListView中可以通過設(shè)置Android:divider屬性來為兩個Item間設(shè)置分割線泣矛。如果想為RecyclerView添加此效果,則必須使用RecyclerView.ItemDecoration禾蚕,這種實現(xiàn)方式不僅更靈活您朽,而且樣式也更加豐富。
? 設(shè)置點擊事件 - 在ListView中存在AdapterView.OnItemClickListener接口换淆,用來綁定條目的點擊事件哗总。但是,很遺憾的是在RecyclerView中倍试,并沒有提供這樣的接口讯屈,不過,提供了另外一個接口RcyclerView.OnItemTouchListener县习,用來響應(yīng)條目的觸摸事件涮母。
但是……,RecyclerView不像ListView那樣擁有Header和Footer躁愿,因此開發(fā)中需要我們自己去實現(xiàn)Header和Foote叛本,另外開發(fā)中小伙伴們經(jīng)常使用的PullToRefresh庫暫時又不支持RecyclerView。和身邊的很多小伙們一樣彤钟,我也陷入了困境来候,為了不拖累項目進(jìn)度,我決定親自解(shi)決(yong)難(kai)題(yuan)逸雹,做一個伸手黨营搅。
現(xiàn)在將我發(fā)現(xiàn)的GitHub上優(yōu)秀的Header、Footer梆砸、上拉加載和下拉刷新解決方案匯總?cè)缦拢?/p>
GitHub地址:https://github.com/Aspsine/SwipeToLoadLayout
SwipeToLoadLayout支持YouTube转质、Google、京東等多家APP基于RecyclerView的上拉加載和下拉刷新樣式帖世,峭拘,好用的不要不要的。廢話不多說狮暑,直接上圖:
? ListView & GridView
? RecyclerView(With all kinds of layoutManagers)
? WebView & ScrollView & Other Views
? Google SwipeRefreshLayout style
? 京東style
? Yalantis Phoenix 樣式
AndroidStudio配置方法
第一步:在你的build.gradle添加JitPack庫在
repositories {
maven { url “https://jitpack.io” }
}
第二部:添加依賴庫
dependencies {
compile ‘com.github.Aspsine:SwipeToLoadLayout:v1.0.2’
}
GitHub地址:https://github.com/cymcsg/UltimateRecyclerView
UltimateRecyclerView是解決RecyclerView下拉刷新,加載更多辉饱,增加頭部搬男,顯示或隱藏工具欄等許多問題的知名開源框架。
包含特性如下:
? Swipe to refresh(usingandroid.support.v4.widget.SwipeRefreshLayout)
? Many kinds of animations
? Swipe to dismiss
? Parallax or normal head view
? Drag and drop items
? Loading more when reach the last item(infinite scrolling)
? Custom views in loading more
? Showing or hiding toolbar and floating button when scrolling
? Scrollbars
? Colorful styles of swipe to refresh
? Sticky header like instagram
? Support different layout in adapter
? Loading adapter with animation
使用效果如下:
AndroidStudio配置方法
第一步:在你的build.gradle添加庫
repositories {
jcenter()
maven { url"http://dl.bintray.com/jjhesk/maven"}
}
第二步:添加依賴庫
dependencies{? ? compile'com.hkm.slidingmenulib:libmenu:0.4.9'}
第三步:布局文件中使用方法
< android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/ultimate_recycler_view"/>
GitHub地址:https://github.com/Aspsine/IRecyclerView
IRecyclerView支持RecyclerView下拉刷新彭沼,上拉加載缔逛,定制Header和Footer。
包含特性如下:
? pull-to-refresh
? pull-to-loadmore
? customize refresh header
? customize loadmore footer
? add multiple header view
? add multiple footer view
使用效果如下:
刷新效果
AndroidStudio配置方法
第一步:在你的build.gradle添加庫
repositories:allprojects {? ? repositories {...maven { url"https://jitpack.io"}? ? }}
第二步:添加依賴庫
dependencies{? ? compile'com.github.Aspsine:IRecyclerView:0.0.2'}
第三步:布局文件中使用方法
< xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/iRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:loadMoreEnabled="true"
app:loadMoreFooterLayout="@layout/layout_irecyclerview_load_more_footer"
app:refreshEnabled="true"
app:refreshHeaderLayout="@layout/layout_irecyclerview_refresh_header"/>
第四步:Activity/Fragment中使用
IRecyclerView iRecyclerView=(IRecyclerView)findViewById(R.id.iRecyclerView);
iRecyclerView.setLayoutManager(newLinearLayoutManager(this));
// an custom footer view, you can customize it yourself.
LoadMoreFooterView loadMoreFooterView=(LoadMoreFooterView)iRecyclerView.getLoadMoreFooterView();
// you can also add header and footer like this
// note: header and refresh header are different, footer and load more footer are different too.
iRecyclerView.addHeaderView(headerView);
iRecyclerView.addFooterView(footerView);
// adapter
ImageAdapter mAdapter=newImageAdapter();
// note: here use setIAdapter(...) method not setAdapter(...)
iRecyclerView.setIAdapter(mAdapter);
iRecyclerView.setOnRefreshListener(newOnRefreshListener(){
@Override
public voidonRefresh(){
}
});
iRecyclerView.setOnLoadMoreListener(newOnLoadMoreListener(){
@Override
public voidonLoadMore(ViewloadMoreView){
}
});
// set auto refreshing
iRecyclerView.post(newRunnable(){
@Override
public voidrun(){
iRecyclerView.setRefreshing(true);
}
});
// stop refreshing
iRecyclerView.setRefreshing(false);
(四)PullLoadMoreRecyclerView-屬性最全
GitHub地址:https://github.com/WuXiaolong/PullLoadMoreRecyclerView
PullLoadMoreRecyclerView實現(xiàn)了RecyclerView下拉刷新和上拉加載更多以及RecyclerView線性、網(wǎng)格褐奴、瀑布流效果按脚。
效果圖如下:
使用方法
build.gradle文件
dependencies{? compile'com.wuxiaolong.pullloadmorerecyclerview:library:1.0.4'}
xml引用
< android:id="@+id/pullLoadMoreRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"/>
設(shè)置線性布局
mPullLoadMoreRecyclerView = (PullLoadMoreRecyclerView) view.findViewById(R.id.pullLoadMoreRecyclerView);mPullLoadMoreRecyclerView.setLinearLayout();
設(shè)置網(wǎng)格布局
mPullLoadMoreRecyclerView.setGridLayout(2);//參數(shù)為列數(shù)
設(shè)置交錯網(wǎng)格布局,即瀑布流效果
mPullLoadMoreRecyclerView.setStaggeredGridLayout(2);//參數(shù)為列數(shù)
綁定適配器
mRecyclerViewAdapter=newRecyclerViewAdapter();
mPullLoadMoreRecyclerView.setAdapter(mRecyclerViewAdapter);
public classRecyclerViewAdapterextendsRecyclerView.Adapter {
publicRecyclerViewAdapter(){
}
@Override
publicViewHolderonCreateViewHolder(ViewGroupparent,intviewType){
Viewview=LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_item,parent,false);
return newViewHolder(view);
}
@Override
public voidonBindViewHolder(ViewHolderholder,intposition){
}
@Override
public intgetItemCount(){
return0;
}
public classViewHolderextendsRecyclerView.ViewHolder{
publicViewHolder(ViewitemView){
super(itemView);
}
}
}
調(diào)用下拉刷新和加載更多
mPullLoadMoreRecyclerView.setOnPullLoadMoreListener(newPullLoadMoreRecyclerView.PullLoadMoreListener(){
@Override
public voidonRefresh(){
}
@Override
public voidonLoadMore(){
}
});
刷新結(jié)束
mPullLoadMoreRecyclerView.setPullLoadMoreCompleted();
不需要下拉刷新
mPullLoadMoreRecyclerView.setPullRefreshEnable(false);
不需要上拉刷新
mPullLoadMoreRecyclerView.setPushRefreshEnable(false);
設(shè)置上拉刷新文字
mPullLoadMoreRecyclerView.setFooterViewText("loading");
設(shè)置下拉刷新顏色
mPullLoadMoreRecyclerView.setColorSchemeResources(android.R.color.holo_red_dark,android.R.color.holo_blue_dark);
快速Top
mPullLoadMoreRecyclerView.scrollToTop();
(五)HeaderAndFooterRecyclerView-封裝完善
GitHub地址:https://github.com/cundong/HeaderAndFooterRecyclerView
HeaderAndFooterRecyclerView是支持addHeaderView敦冬、 addFooterView辅搬、分頁加載的RecyclerView解決方案。它可以對 RecyclerView 控件進(jìn)行拓展(通過RecyclerView.Adapter實現(xiàn))脖旱,給RecyclerView增加HeaderView堪遂、FooterView,并且不需要對你的具體業(yè)務(wù)邏輯Adapter做任何修改萌庆。同時溶褪,通過修改 FooterView State,可以動態(tài) FooterView 賦予不同狀態(tài)(加載中践险、加載失敗猿妈、滑到最底等),可以實現(xiàn) RecyclerView 分頁加載數(shù)據(jù)時的 Loading/TheEnd/NetWorkError 效果巍虫。
? 添加HeaderView彭则、FooterView
mHeaderAndFooterRecyclerViewAdapter = new HeaderAndFooterRecyclerViewAdapter(mDataAdapter);
mRecyclerView.setAdapter(mHeaderAndFooterRecyclerViewAdapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
//add a HeaderView
RecyclerViewUtils.setHeaderView(mRecyclerView, new SampleHeader(this));
//add a FooterView
RecyclerViewUtils.setFooterView(mRecyclerView, new SampleFooter(this));
? LinearLayout/GridLayout/StaggeredGridLayout布局的RecyclerView分頁加載
mRecyclerView.addOnScrollListener(mOnScrollListener);
private EndlessRecyclerOnScrollListener mOnScrollListener = new EndlessRecyclerOnScrollListener() {
@Override
public void onLoadNextPage(View view) {
super.onLoadNextPage(view);
LoadingFooter.State state = RecyclerViewStateUtils.getFooterViewState(mRecyclerView);
if(state == LoadingFooter.State.Loading) {
Log.d("@Cundong", "the state is Loading, just wait..");
return;
}
mCurrentCounter = mDataList.size();
if (mCurrentCounter < TOTAL_COUNTER) {
// loading more
RecyclerViewStateUtils.setFooterViewState(EndlessLinearLayoutActivity.this, mRecyclerView, REQUEST_COUNT, LoadingFooter.State.Loading, null);
requestData();
} else {
//the end
RecyclerViewStateUtils.setFooterViewState(EndlessLinearLayoutActivity.this, mRecyclerView, REQUEST_COUNT, LoadingFooter.State.TheEnd, null);
}
}
};
注意事項
如果已經(jīng)使用 RecyclerViewUtils.setHeaderView(mRecyclerView, view); 為RecyclerView添加了HeaderView,那么再調(diào)用ViewHolder類的getAdapterPosition()垫言、getLayoutPosition()時返回的值就會因為增加了Header而受影響(返回的position等于真實的position+headerCounter)贰剥。
因此,這種情況下請使用 RecyclerViewUtils.getAdapterPosition(mRecyclerView, ViewHolder.this)筷频、RecyclerViewUtils.getLayoutPosition(mRecyclerView, ViewHolder.this) 兩個方法來替代蚌成。
使用效果:
? 添加HeaderView、FooterView
? 支持分頁加載的LinearLayout布局RecyclerView
? 支持分頁加載的GridLayout布局RecyclerView
? 支持分頁加載的StaggeredGridLayout布局RecyclerView
? 分頁加載失敗時的GridLayout布局RecyclerView