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

来源:互联网 发布:淘宝店铺商品被删除 编辑:程序博客网 时间:2024/06/05 09:47

PracticalRecyclerView

项目地址:ssseasonnn/PracticalRecyclerView
简介:封装 RecyclerView, 打造为一个非常实用的开发工具 , 添加一些开发中常用的功能 , 例如下拉刷新, 分页, 自动加载 , 加载错误等等
更多:作者   提 Bug   
标签:
recyclerview-

Encapsulation RecyclerView, to create for the development of a very practical tool, add some commonly used in the development of function, such as drop-down refresh, paging, automatic loading, loading error, etc.More new functions will gradually add...

标签(空格分隔): Android RecyclerView


对 RecyclerView 的一个封装,添加一些实用的功能

主要功能:

  • 下拉刷新,使用默认的下拉刷新控件
  • 页面加载数据过程中显示 LoadingView
  • 页面加载数据出错时显示 ErrorView
  • 页面数据大小为 0 时显示 EmptyView
  • 自动加载,当页面到底部或者当前页面显示不全时,自动加载其余数据,并显示 LoadMoreView
  • 加载更多时出错自动停止加载更多,并显示 LoadMoreFailedView
  • 没有更多数据加载时,显示 NoMoreView
  • 支持 Header View 和 Footer View
  • 除下拉刷新以外,其余 View 均可自定义
  • 支持多种 Item 类型
  • 支持 GridLayout 和瀑布流

2016-10-11 更新:

  • 新增动态显示或关闭 NoMoreView,LoadMoreView,LoadMoreFailedView 功能
  • 新增打开或关闭自动加载功能
  • 新增手动触发加载 demo

2016-10-17 更新:

  • 增加获取 RecyclerView 接口
    public RecyclerView get() {            return mRecyclerView;    }
  • 增加拖拽功能与 demo

2016-10-18 更新:

  • 向下支持到 API 11(android 3.0)
  • AbstractAdapter 增加更多操作数据接口, 如:
    public void clearData() {}    public void clearHeader() {}    public void clearFooter() {}    public void insert(){}    public void insertBack(){}    //等等
  • 增加 ExpandItemList demo

2016-11-7 更新:

  • 新增添加单个数据接口 void add(T item);

2017-1-22 更新

  • 修复需要滑动两次才能显示 loadmore 的 bug.

效果图

 

  

使用方式:

1.添加 Gradle 依赖

Download

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

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.

关于我

若您对该项目有疑问,请联系我:

QQ:270362455

Gmail: ssseasonnn@gmail.com

阅读全文
0 0