美文网首页AndroidAndroid进阶之旅Android 开发技术分享
如何简单的为Recycleview实现刷新和加载更多

如何简单的为Recycleview实现刷新和加载更多

作者: fodroid | 来源:发表于2017-02-15 11:34 被阅读1897次

    在RecyclerView问世之前,ListView可能是我们使用频率最高的控件之一了。而随着Android的发展,越来越多的时候大家都开始选择使用RecyclerView了。当然这也是事物发展的必然,个人感觉最重要的原因就是RecyclerView相对来说使用灵活性更高。

    默认情况下RecyclerView是不带下拉刷新和上拉加载更多效果的,但在实际项目中,经常需要添加这两项功能。虽然现成的库也有很多,但我们经常只需要最基本的下拉刷新和上拉加载更多功能,而不需要其他多余功能。所以简单的封装了一个,取名为:XRecycleview

    XRecycleview的主要功能:

    • 官方Material Design风格。
    • 支持自动刷新、下来刷新、自动加载更多。
    • 支持添加多个Header和Footer。
    • 封装了RecyclerAdapter,使用更方便。
    运行效果

    实现原理

    实现原理
    其中下拉刷新使用了官方的SwipeRefreshLayout ,然后为了方便的添加header和footer ,在里面放了一个ScrollView,然后在ScrollView里面包裹LinearLayoutRecycleView,上拉到底部自动加载更多监听ScrollView来实现。为了实现Material Design风格ProgressBar使用了DreaminginCodeZH的开源库,大家可以去详细了解。(MaterialProgressBar传送门

    具体实现

    1.首先来看具体的布局文件
    <pre><code>
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v4.widget.NestedScrollView
    android:id="@+id/scrollView"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

        <LinearLayout
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:orientation="vertical">
    
        <LinearLayout
            android:id="@+id/ll_header"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
    
        </LinearLayout>
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    
        <LinearLayout
            android:id="@+id/ll_footer"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
    
        </LinearLayout>
    
        <LinearLayout
            android:id="@+id/ll_loadmore"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:gravity="center"
            android:orientation="horizontal">
    
            <me.zhanghai.android.materialprogressbar.MaterialProgressBar
                android:id="@+id/progressBar"
                style="@style/Widget.MaterialProgressBar.ProgressBar.NoPadding"
                android:layout_width="22dp"
                android:layout_height="22dp"
                android:layout_marginRight="16dp"/>
    
            <TextView
                android:id="@+id/textView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="加载中..."
                android:textColor="#60000000"
                android:textSize="14sp"/>
        </LinearLayout>
    </LinearLayout>
    

    </android.support.v4.widget.NestedScrollView>
    </code></pre>
    2.XRecyclerView实现的主要代码

    • 初始化绑定控件
      <pre><code>
      LayoutInflater.from(context).inflate(R.layout.layout_xrecyclerview, this);
      scrollView = (NestedScrollView) findViewById(R.id.scrollView);
      recyclerView = (RecyclerView) findViewById(R.id.recycler);
      textView = (TextView) findViewById(R.id.textView);
      progressBar = (MaterialProgressBar) findViewById(R.id.progressBar);
      llLoadMoreView = (LinearLayout) findViewById(R.id.ll_loadmore);
      llHeader = (LinearLayout) findViewById(R.id.ll_header);
      llFooter = (LinearLayout) findViewById(R.id.ll_footer);
      </code></pre>

    • 添加刷新接口
      <pre><code>
      private OnRefreshListener refreshListener;

      public void setOnRefreshListener(OnRefreshListener listener) {
      this.refreshListener = listener;
      }
      public interface OnRefreshListener {
      void onRefresh();

        void onLoadMore();
      

      }
      </code></pre>

    • 初始化刷新

      private void initSwipeRefreshLayout() {
        super.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                if (refreshListener != null)
                    refreshListener.onRefresh();
            }
        });
        setColorSchemeColors(getColorAccent());
      }
      
      private int getColorAccent() {
        int accentColor = 0xFF9800;
        int[] attrsArray = {R.attr.colorAccent};
        TypedArray typedArray = getContext().obtainStyledAttributes(attrsArray);
        try {
            accentColor = typedArray.getColor(0, accentColor);
        } catch (Exception e) {
            e.printStackTrace();
        }
        typedArray.recycle();
        return accentColor;
      }
      
    • 监听滑动,满足条件开始加载更多。
      private void initRecyclerView() {
      recyclerView.setNestedScrollingEnabled(false);
      scrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
      @Override
      public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
      Log.d(TAG, "scrollY = " + scrollY + ",oldScrollY = " + oldScrollY);
      scrollDistance = scrollY;
      int maxScrollAmount = v.getChildAt(0).getMeasuredHeight() - +v.getHeight();
      Log.d(TAG, "scrollDistance = " + scrollDistance + ",maxScrollAmount = " + maxScrollAmount);
      if (scrollDistance >= maxScrollAmount - 80) {
      if (!isRefreshing() && !isLoadMore && isCanLoadMore) {
      Log.d(TAG, "加载更多...");
      //加载更多
      if (refreshListener != null) {
      loadMore(true);
      refreshListener.onLoadMore();
      }
      }
      }
      }
      });
      }

    • 增加移除Header和Footer
      public void addHeaderView(View view) {
      if (llHeader != null && view != null)
      llHeader.addView(view);
      }

      public void removeHeaderView(View view) {
        if (llHeader != null && view != null)
            llHeader.removeView(view);
      }
      
      public void removeHeaderView(int index) {
        if (llHeader != null && index >= 0 && index < llHeader.getChildCount())
            llHeader.removeViewAt(index);
      }
      
      public void removeAllHeaderView() {
        if (llHeader != null)
            llHeader.removeAllViews();
      }
      
      public void addFooterView(View view) {
        if (llFooter != null && view != null)
            llFooter.addView(view);
      }
      
      public void removeFooterView(View view) {
        if (llFooter != null && view != null)
            llFooter.removeView(view);
      }
      
      public void removeFooterView(int index) {
        if (llFooter != null && index >= 0 && index < llFooter.getChildCount())
            llFooter.removeViewAt(index);
      }
      
      public void removeAllFooterView() {
        if (llFooter != null)
            llFooter.removeAllViews();
      }
      

    详细的实现可以参考在Github上的代码:XRecycleview

    如何使用

    1.在xml中引入XRecyclerView

      <me.shihao.library.XRecyclerView 
          android:id="@+id/recyclerview"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"/>
    

    2.在java代码中设置

        xRecyclerView = (XRecyclerView) findViewById(R.id.recyclerview);
        adapter = new TestAdapter(this);
        xRecyclerView.verticalLayoutManager().setAdapter(adapter);
        //xRecyclerView.horizontalLayoutManager().setAdapter(adapter);
    

    3.设置刷新监听

          xRecyclerView.setOnRefreshListener(new XRecyclerView.OnRefreshListener() {
            @Override
            public void onRefresh() {
                //刷新
            }
    
            @Override
            public void onLoadMore() {
                //加载更多
           }
        });
    

    4.数据获取完成后通知界面必须调用

      xRecyclerView.refreshComlete();
    

    详细的实现可以参考在Github上的代码:XRecycleview

    gradle快速集成

    allprojects {
    repositories {
        ...
        maven { url 'https://www.jitpack.io' }
      }
    }
    
    dependencies {
        compile 'com.github.fodroid:XRecyclerView:v1.0'
    }
    

    如果你觉得有用,请在Github不吝给我一个Star,非常感谢。


    写在最后的话:个人能力有限,欢迎大家在下面吐槽。喜欢的话就为我点一个赞吧。也欢迎 Fork Me On Github 。

    相关文章

      网友评论

      • 李楠_be99:列表不满屏,源码里的 this.scrollView.setOnScrollChangeListener监听不到上拉加载的滑动

      本文标题:如何简单的为Recycleview实现刷新和加载更多

      本文链接:https://www.haomeiwen.com/subject/szsfwttx.html