Android RecyclerView上拉加载和下拉刷新(基础版)
这里讲述的是用谷歌原生的SwipeRefreshLayout,进行刷新,以及利用RecycleView的滚动事件,判断是否到最后一个item,进行加载更多,这里加载更多是在RecycleView的适配器中使用不同item进行完成的。
这是activity的xml布局:
<?xmlversion="1.0"encoding="utf-8"?> <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swipe_refresh_layout" android:layout_width="match_parent" android:layout_height="match_parent" > <android.support.v7.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#F0F0F0" android:clipToPadding="false" android:paddingBottom="16dp" android:paddingTop="16dp"/> </android.support.v4.widget.SwipeRefreshLayout> <com.rey.material.widget.ProgressView android:id="@+id/progress_loading_main" app:pv_autostart="true" app:pv_circular="true"app:pv_progressStyle="@style/Material.Drawable.CircularProgress" app:pv_progressMode="indeterminate" android:layout_width="50dp" android:layout_height="50dp" android:visibility="gone" android:layout_centerInParent="true"/> </RelativeLayout>
接下来是对应activity中的代码:
importandroid.os.Bundle;
importandroid.os.Handler;
importandroid.support.annotation.Nullable;
importandroid.support.design.widget.Snackbar;
importandroid.support.v4.app.Fragment;
importandroid.support.v4.widget.SwipeRefreshLayout;
importandroid.support.v7.widget.LinearLayoutManager;
importandroid.support.v7.widget.RecyclerView;
importandroid.view.LayoutInflater;
importandroid.view.View;
importandroid.view.ViewGroup;
importcom.retrofit.wangfei.viewpagertablayout.util.Constance;
importcom.retrofit.wangfei.viewpagertablayout.R;
importcom.retrofit.wangfei.viewpagertablayout.adapter.MyRecycleViewAdapter;
importcom.rey.material.widget.ProgressView;
importjava.util.ArrayList;
importjava.util.List;
importbutterknife.Bind;
importbutterknife.ButterKnife;
publicclassHomeFragmentextendsFragment{
@Bind(R.id.recyclerview)
RecyclerViewrecyclerview;
@Bind(R.id.swipe_refresh_layout)
SwipeRefreshLayoutswipeRefreshLayout;
@Bind(R.id.progress_loading_main)
ProgressViewprogress_loading_main;//加载数据时显示的进度圆圈
privateLinearLayoutManagermRecycleViewLayoutManager;
privateintmPageNum=1;
privateList<String>lists=newArrayList<>();
privateMyRecycleViewAdaptermAdapter;
publicstaticHomeFragmentnewInstance(){
HomeFragmentfragment=newHomeFragment();
returnfragment;
}
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
}
@Override
publicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,
BundlesavedInstanceState){
Viewview=inflater.inflate(R.layout.fragment_home,container,false);
ButterKnife.bind(this,view);
returnview;
}
/**在onCreateView方法后执行*/
@Override
publicvoidonViewCreated(Viewview,@NullableBundlesavedInstanceState){
super.onViewCreated(view,savedInstanceState);
mAdapter=newMyRecycleViewAdapter(lists,getActivity());
initRecyclerView();
swipeRefreshLayout.setColorSchemeResources(Constance.colors);//设置下拉刷新控件变换的四个颜色
recyclerview.setAdapter(mAdapter);
recyclerViewOnItemClickListener();
refresh();
loadMore(mAdapter);
progress_loading_main.setVisibility(View.VISIBLE);
initData();
}
@Override
publicvoidonDestroyView(){
super.onDestroyView();
ButterKnife.unbind(this);
}
/**进入页面的初始化数据*/
privatevoidinitData(){
newHandler().postDelayed(newRunnable(){
@Override
publicvoidrun(){
netNewsList(true);
progress_loading_main.setVisibility(View.GONE);
}
},2000);
}
/**RecyclerView每个item的点击事件*/
privatevoidrecyclerViewOnItemClickListener(){
mAdapter.setOnItemClickListener(newMyRecycleViewAdapter.OnItemClickListener(){
@Override
publicvoidonItemClick(Viewview,intposition){
Snackbar.make(view,"fly",Snackbar.LENGTH_SHORT).show();
}
});
}
/**
*初始化RecyclerView
*/
privatevoidinitRecyclerView(){
//recyclerview.setItemAnimator(newDefaultItemAnimator());
//recyclerview.setHasFixedSize(true);
mRecycleViewLayoutManager=newLinearLayoutManager(getActivity());
recyclerview.setLayoutManager(mRecycleViewLayoutManager);//设置RecycleView,显示是ListView还是gridView还是瀑布流
}
/**下拉刷新*/
privatevoidrefresh(){
swipeRefreshLayout.setOnRefreshListener(newSwipeRefreshLayout.OnRefreshListener(){
@Override
publicvoidonRefresh(){
newHandler().postDelayed(newRunnable(){
@Override
publicvoidrun(){
netNewsList(true);
swipeRefreshLayout.setRefreshing(false);//停止刷新
}
},2000);
}
});
}
/**
*设置上拉加载更多
*
*@paramadapterRecyclerView适配器
*/
publicvoidloadMore(finalMyRecycleViewAdapteradapter){
recyclerview.addOnScrollListener(newRecyclerView.OnScrollListener(){
privateintlastVisibleItem;
@Override
publicvoidonScrolled(RecyclerViewrecyclerView,intdx,intdy){
super.onScrolled(recyclerView,dx,dy);
lastVisibleItem=mRecycleViewLayoutManager.findLastVisibleItemPosition();//滑动到最后一个
}
@Override
publicvoidonScrollStateChanged(RecyclerViewrecyclerView,intnewState){
super.onScrollStateChanged(recyclerView,newState);
//效果在暂停时显示,否则会导致重绘异常
if(newState==RecyclerView.SCROLL_STATE_IDLE
&&lastVisibleItem+1==adapter.getItemCount()){
if(lists!=null&&lists.size()>=10){//真实开发中要设置mNews.size()大于加载分页显示的个数
adapter.loadLayout.setVisibility(View.VISIBLE);
//加载更多
newHandler().postDelayed(newRunnable(){
@Override
publicvoidrun(){
netNewsList(false);
}
},2000);
}
}
}
});
}
/**
*从网络加载数据列表
*
*@paramisRefresh是否刷新true为刷新,false为不刷新
*/
privatevoidnetNewsList(booleanisRefresh){
//viewDelegate.showLoading();
if(isRefresh){
mPageNum=1;
}else{
mPageNum++;
}
if(isRefresh){
if(!lists.isEmpty()){
lists.clear();
}
}
//TODO这里把页数mPageNum上传到服务端
lists.clear();
lists.addAll(getData());
mAdapter.notifyDataSetChanged();
}
privateList<String>list=newArrayList<>();
privateList<String>getData(){
for(inti=0;i<10;i++){
list.add(i+"");
}
returnlist;
}
}
接下来是RecycleView适配器中的xml文件:
这是正常item的布局,至于用CardView是为了让item展示出来的效果更好看
<?xmlversion="1.0"encoding="utf-8"?> <android.support.v7.widget.CardViewxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical"android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/text" android:layout_width="match_parent" android:layout_height="50dp" android:text="" android:gravity="center"/> </android.support.v7.widget.CardView>
这是现实上拉加载的布局文件,作为不同item共同展示在RecycleView上面:
<?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/load_layout" android:visibility="gone" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal" android:paddingBottom="12dip" android:paddingTop="12dip"> <com.rey.material.widget.ProgressView app:pv_autostart="true" app:pv_circular="true" app:pv_progressStyle="@style/Material.Drawable.CircularProgress" app:pv_progressMode="indeterminate" android:layout_width="24dp" android:layout_height="24dp"/> <TextView android:id="@+id/more_data_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="16sp" android:layout_marginLeft="10dp" android:text="正在加载..."/> </LinearLayout>
下面我们看看RecycleView适配器的写法:
importandroid.app.Activity;
importandroid.support.v7.widget.RecyclerView;
importandroid.view.LayoutInflater;
importandroid.view.View;
importandroid.view.ViewGroup;
importandroid.widget.LinearLayout;
importandroid.widget.TextView;
importcom.retrofit.wangfei.viewpagertablayout.R;
importjava.util.List;
importbutterknife.Bind;
importbutterknife.ButterKnife;
/**
*CreatedbyAndroidStudio
*Description:RecycleView的适配器
*/
publicclassMyRecycleViewAdapterextendsRecyclerView.Adapter{
privatefinalstaticintTYPE_ITEM=0X01;
privatefinalstaticintTYPE_FOOTER=0x02;
privateList<String>lists;
privateActivitycontext;
publicLinearLayoutloadLayout;
privateOnItemClickListenermOnItemClickListener;//声明接口
publicMyRecycleViewAdapter(List<String>lists,Activitycontext){
this.lists=lists;
this.context=context;
}
@Override
publicRecyclerView.ViewHolderonCreateViewHolder(ViewGroupparent,intviewType){
if(TYPE_ITEM==viewType){
Viewview=LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_view_item,parent,false);
ItemViewHolderitemViewHolder=newItemViewHolder(view);
returnitemViewHolder;
}else{
Viewview=LayoutInflater.from(parent.getContext()).inflate(R.layout.list_footer,parent,false);
loadLayout=(LinearLayout)view.findViewById(R.id.load_layout);
returnnewFootViewHolder(view);
}
}
@Override
publicvoidonBindViewHolder(RecyclerView.ViewHolderholder,intposition){
if(holderinstanceofItemViewHolder){
Stringtext=lists.get(position);
ItemViewHolderitemHolder=(ItemViewHolder)holder;
itemHolder.text.setText(text);
}
}
@Override
publicintgetItemCount(){
returnlists.size()+1;
}
@Override
publicintgetItemViewType(intposition){
if(position+1==getItemCount()){
returnTYPE_FOOTER;
}else{
returnTYPE_ITEM;
}
}
publicclassItemViewHolderextendsRecyclerView.ViewHolderimplementsView.OnClickListener{
@Bind(R.id.text)
TextViewtext;
publicItemViewHolder(ViewitemView){
super(itemView);
ButterKnife.bind(this,itemView);
itemView.setOnClickListener(this);
}
@Override
publicvoidonClick(Viewv){
mOnItemClickListener.onItemClick(v,getPosition());
}
}
publicclassFootViewHolderextendsRecyclerView.ViewHolder{
publicFootViewHolder(ViewitemView){
super(itemView);
}
}
/**调到外部使用*/
publicvoidsetOnItemClickListener(OnItemClickListeneronItemClickListener){
this.mOnItemClickListener=onItemClickListener;
}
/**定义接口*/
publicinterfaceOnItemClickListener{
voidonItemClick(Viewv,intposition);
}
}
最后是刷新控件的4个不同颜色:
publicinterfaceConstance{
/**
*下拉刷新控件变化的四个颜色
*/
int[]colors=newint[]{
android.R.color.holo_green_light,android.R.color.holo_blue_light,
android.R.color.holo_green_light,android.R.color.holo_blue_light
};
}
所需要的依赖库:
compile'com.android.support:appcompat-v7:23.3.0' compile'com.android.support:design:23.3.0' compile'com.jakewharton:butterknife:7.0.1' compile'com.android.support:support-v4:23.3.0' /**谷歌服务*/ compile'com.google.android.gms:play-services:8.4.0' compile'com.github.rey5137:material:1.2.2'
到这里就结束了,完成了下拉刷新和上拉加载更多的实现。
下面说说RecyclerView的使用最基础的三点:
一:
recyclerview.setHasFixedSize(true); //方法用来使RecyclerView保持固定的大小,该信息被用于自身的优化。
二:
recyclerview.setItemAnimator(newDefaultItemAnimator());
ItemAnimator会根据适配器上收到的通知动画显示视图组的修改。基本上,它会自动显示添加和移除条目动画。这也不是一个简单的类,但我们发现DefaultItemAnimator已经可以运行得很好了。
三:
recyclerview.setLayoutManager(mRecycleViewLayoutManager); //设置RecycleView,显示是ListView还是gridView还是瀑布流。 //显示是ListView LinearLayoutManagermRecycleViewLayoutManager=newLinearLayoutManager(context); //显示是gridView,参数一:上下文,参数二:列数 GridLayoutManagermGridLayoutManager=newGridLayoutManager(context,4); //显示是瀑布流,参数一:显示几列,参数二:现实的方向,垂直或水平 StaggeredGridLayoutManagermStaggeredGridLayoutManager=newStaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
更多详细请参考:AndroidRecyclerView艺术般的控件使用完全解析
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。