PracticalRecyclerView - 封装RecyclerView, 打造为一个非常实用的开发工具 , 添加一些开发中常用的功能 , 例如下拉刷新, 分页, 自动加载 , 加载错误等

项目地址

PracticalRecyclerView

效果图与示例APK

single item

multi item

grid

stagger

主要功能:

·下拉刷新,使用默认的下拉刷新控件

·页面加载数据过程中显示LoadingView

·页面加载数据出错时显示ErrorView

·页面数据大小为0时显示EmptyView

·自动加载,当页面到底部或者当前页面显示不全时,自动加载其余数据,并显示LoadMoreView

·加载更多时出错自动停止加载更多,并显示LoadMoreFailedView

·没有更多数据加载时,显示NoMoreView

·支持Header View和Footer View

·除下拉刷新以外,其余View均可自定义

·支持多种Item类型

·支持GridLayout和瀑布流

·支持动态显示或关闭NoMoreView,LoadMoreView,LoadMoreFailedView功能

·支持打开或关闭自动加载功能

·支持拖拽功能

·支持ExpandItemList

·向下支持到API 11(android 3.0)

使用方式:

1.添加Gradle依赖

Download

    dependencies{
         compile 'zlc.season:practicalrecyclerview:1.0.8'
    }

2.在布局文件中添加PracticalRecyclerView

     <zlc.season.practicalrecyclerview.PracticalRecyclerView        
         android:id="@+id/recycler"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:loading_layout="@layout/default_loading_layout" //可以自定义,也可以不设置使用默认的布局        
        app:empty_layout="@layout/default_empty_layout"     //以下属性同样不设置即为使用默认的布局        
        app:error_layout="@layout/default_error_layout"
        app:load_more_layout="@layout/default_load_more_layout"
        app:no_more_layout="@layout/default_no_more_layout"
        app:load_more_failed_layout="@layout/default_load_more_failed_layout"/>

3.添加代码

首先定义一个POJO类, 并实现ItemType接口:

   class NormalBean implements ItemType {       
           String mImg;       
           String mTitle;       
           String mContent;    
              
           NormalBean(String img, String title, String content) {
               mImg = img;
               mContent = content;
               mTitle = title;
           }       
           
           @Override
           public int itemType() {          
                return 0;
           }
       }

这里返回的item type 表示是item的类型, 如果列表只有一种类型的item, 那么返回0就可以了, 如果有多种item, 则对应类型的item返回对应类型的item type. 这里简单的返回0 .

接着定义ViewHolder, 继承自AbstractViewHolder, 并提供泛型参数:

   class NormalViewHolder extends AbstractViewHolder<NormalBean> {       
           @BindView(R.id.head)       
           ImageView mHead;       
           @BindView(R.id.title)       
           TextView mTitle;       
           @BindView(R.id.content)       
           TextView mContent;    
              
           private Context mContext;  
                
           NormalViewHolder(ViewGroup parent) {           
               super(parent, R.layout.normal_item); //与对应的item layout进行绑定.
               mContext = parent.getContext();      //如果viewholder需要context,在这里获取.
               ButterKnife.bind(this, itemView);    //这里使用了butterknife进行控件绑定,也可以手写      
                                                    // itemView.findViewById()来获取对应的控件.
           }       
           
           @Override
           public void setData(NormalBean data) {           
               Picasso.with(mContext).load(Uri.parse(data.mImg)).into(mHead);
               mTitle.setText(data.mTitle);
               mContent.setText(data.mContent);
           }
       }

在Viewholder中进行View的创建和绑定, 如果需要绑定按钮的单击事件或者其他的一些事件, 在此处进行再好不过了.

接下来创建Adatper, 继承自AbstractAdapter, 并提供泛型参数:

   class SingleItemAdapter extends AbstractAdapter<NormalBean, NormalViewHolder> {       
       
       @Override
       protected NormalViewHolder onNewCreateViewHolder(ViewGroup parent, int viewType) {          
               return new NormalViewHolder(parent);
       }      
       
       @Override
       protected void onNewBindViewHolder(NormalViewHolder holder, int position) {
           holder.setData(get(position));
       }
   }

adapter 类中非常简洁, 只需要在onNewCreateViewHolder()中创建ViewHolder, 在onNewBindViewHolder()中调用viewholder的setData()即可, 这样adapter和viewholder的逻辑就分离开来,互不干扰.

最后,在Activity或者Fragment中进行最后的配置:

   PracticalRecyclerView mRecycler;   
   private SingleItemAdapter mAdapter = new SingleItemAdapter();   
   ...
   
   mRecycler.setLayoutManager(new LinearLayoutManager(this));
   mRecycler.setAdapterWithLoading(mAdapter);
   mRecycler.setRefreshListener(new PracticalRecyclerView.OnRefreshListener() {               
               @Override
               public void onRefresh() {
                   mPresenter.loadData(true);
               }
           });
   mRecycler.setLoadMoreListener(new PracticalRecyclerView.OnLoadMoreListener() {              
               @Override
               public void onLoadMore() {
                   mPresenter.loadData(false);
               }
            });   ...
   //更多详细代码请下载demo查看

4.添加Header 和 Footer

要添加Header和Footer, 可以选择实现SectionItem接口, 或者继承SectionItemImpl, 如下所示:

   class Header implements SectionItem {           
           @BindView(R.id.banner_guide_content)           
           BGABanner mBanner;           
           
           @Override
           public View createView(ViewGroup parent) {               
                   View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.header_item, parent, false);             
                   ButterKnife.bind(this, view);               
                   return view;
           }          
           
           @Override
           public void onBind() {
               mBanner.setAdapter(new BGABanner.Adapter() {                   
                   @Override
                   public void fillBannerItem(BGABanner banner, View view, Object model, int position) {
                       ((ImageView) view).setImageResource((int) model);
                   }
               });
               mBanner.setData(Arrays.asList(R.mipmap.a, R.mipmap.b, R.mipmap.c, R.mipmap.d, R.mipmap.e, R.mipmap.f,                       
                                               R.mipmap.g, R.mipmap.h), null);
           }
       }

这里使用了一个开源轮播库BGABanner当作Header, 该库的链接在此: BGAbanner

接着调用Adapter的addHeader() 或者addFooter()方法将该Header或Footer添加到adapter中:

    mAdapter.addHeader(new Header());

5.Configure 接口和ConfigureAdapter类

当默认的属性不能满足需求时, 可以自定义layout 并设置为PracticalRecyclerView的属性:

   ...
   app:load_more_failed_layout="@layout/custom_load_more_failed_layout"  //当加载更多失败时显示的View
   ...

若需要对该View进行设置, 就需要用到Configure接口, Configure接口定义了以下方法,分别对属性中设置的View进行设置:

   public interface Configure {       
       void configureEmptyView(View emptyView); //对Empty View 进行设置
       void configureErrorView(View errorView); //对Error View 进行设置
       void configureLoadingView(View loadingView); // 对LoadingView 进行设置
       void configureLoadMoreView(View loadMoreView); // 对LoadMore View进行设置
       void configureNoMoreView(View noMoreView); //对NoMore View进行设置
       void configureLoadMoreErrorView(View loadMoreErrorView); // 对LoadMoreError View进行设置
   }

ConfigureAdapter是对Configure接口的一个包装类, 可以选择实现其中的某一些方法,从而设置对应的View:

    mRecycler.configureView(new ConfigureAdapter() {               
                @Override
               public void configureLoadMoreFailedView(View loadMoreFailedView) {                   
                   super.configureLoadMoreFailedView(loadMoreFailedView);
                   loadMoreFailedView.setOnClickListener(new View.OnClickListener() {                       
                       @Override
                       public void onClick(View v) {                           
                           Toast.makeText(SingleItemActivity.this, "点击LoadMoreFailedView时应该进行的操作", Toast.LENGTH_SHORT).show();
                       }
                   });
               }               
               
               @Override
               public void configureErrorView(View errorView) {                   
                   super.configureErrorView(errorView);
                   errorView.dosomething();
               }
           });

6.更多功能将会继续开发和完善

若您对此项目有一些自己的想法 , 欢迎来提Pull Request.