mint-ui loadmore组件注意难点分分快三计划

作者:分分快三计划
this.$refs.loadmore.onTopLoaded();

知道自己不能做什么远比知道自己能做什么重要。

分分快三计划 1

这行代码,否则下拉加载之后一直显示加载中,而不会加载完成。

分分快三计划 2

下拉刷新和上拉加载这两个功能,一开始给人的感觉就是它们是一个组合,它们之间是不是存在什么关系,但是事实上,实现的方式是完全不一样的。下面我将结合核心部分代码来讲一下它们的实现。

比如在做下拉刷新的时候,切记在下拉刷新的函数中要加 

RecyclerView是Android L版本中新添加的控件,它的灵活性、可替代性、回收机制等比listview更好。可能对于一些使用过RecyclerView的开发者会说,RecyclerView是用来替代ListView的。说RecyclerView是用来代替ListView就太严重了,不过确实是一个不错的控件。

mRefreshLayout.setOnRefreshListener(new OnRefreshListener(){
 public void onRefresh() {
  //我在List最前面加入一条数据
 mData.add(0, "嘿,我是“下拉刷新”生出来的");

 //数据重新加载完成后,提示数据发生改变,并且设置现在不在刷新
 mAdapter.notifyDataSetChanged();
 mRefreshLayout.setRefreshing(false);
 }
});
loadTop(){
        this.$store.dispatch('getNewsList',{channelId:this.id,page:0,size:this.size});
        this.$refs.loadmore.onTopLoaded();
},

实现

首先看一下最终实现的效果图:

分分快三计划 3

RecyclerView下拉刷新与加载更多效果图

当应用程序打开的时候,进行数据加载,并显示下拉刷新的效果,加载完成之后显示数据。当下拉到底部的时候,显示加载更多效果,并加载数据,数据加载完成之后显示数据。

一、布局

根据上面的分析和封装的类进行页面布局。

<?xml version="1.0" encoding="utf-8"?>  
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent">  

    <cc.ibooker.zrecyclerview.view.AutoSwipeRefreshLayout  
        android:id="@ id/swipe_container"  
        android:layout_width="match_parent"  
        android:layout_height="match_parent">  

        <cc.ibooker.zrecyclerview.view.LoadRecyclerView  
            android:id="@ id/recyclerview"  
            android:layout_width="match_parent"  
            android:layout_height="match_parent" />  

    </cc.ibooker.zrecyclerview.view.AutoSwipeRefreshLayout>  

</RelativeLayout>  

AutoSwipeRefreshLayout是AutoSwipeRefreshLayout的父控件,用来实现自动刷新和下拉刷新功能。LoadRecyclerView是用来实现加载更多以及呈现列表。

二、下拉刷新实现

实现下拉刷新效果,需要在实现类中继承SwipeRefreshLayout.OnRefreshListener,并实现下拉刷新onRefresh方法。最后让AutoSwipeRefreshLayout设置下拉刷新监听即可。

swipeLayout = (AutoSwipeRefreshLayout) findViewById(R.id.swipe_container);  
swipeLayout.setColorSchemeResources(android.R.color.holo_blue_bright,  
        android.R.color.holo_green_light,  
        android.R.color.holo_orange_light,  
        android.R.color.holo_red_light);  
swipeLayout.setOnRefreshListener(this);  

// 下拉刷新-一般为加载网络数据  
@Override  
public void onRefresh() {  
    // 获取最新数据  
    isAbleLoading = true;  
    // 模拟网络加载  
    new Handler().postDelayed(new Runnable() {  
        @Override  
        public void run() {  
            if (mDatas == null)  
                mDatas = new ArrayList<>();  
            mDatas.clear();  
            for (int i = 0; i < ConstantUtil.PAGE_SIZE; i  ) {  
                RvData rvData = new RvData();  
                rvData.setTitle("标题="   i);  
                rvData.setDesc("描述="   i);  
                rvData.setType(RvAdapter.TYPE_ONE);  
                mDatas.add(rvData);  
            }  
            setAdapter();  
            // 取消加载  
            swipeLayout.setRefreshing(false);  
        }  
    }, 3000);  

    reflashFooterView(ConstantUtil.LOAD_MORE_BEFORE);  
}  

为了避免下拉刷新和加载更多同时进行,所以添加一个boolean值isAbleLoading来控制是否可以加载更多。mDatas是用来保存数据的集合。当数据加载完成之后利用自定义setAdapter()方法来刷新列表,利用swipeLayout.setRefreshing(false)方法取消加载状态。每一次加载完数据都要重置底部加载更多布局,这里是利用reflashFooterView()方法来实现。

// 自定义setAdapter  
private void setAdapter() {  
    if (adapter == null) {  
        adapter = new RvAdapter(this, mDatas, footerData);  
        recyclerView.setAdapter(adapter);  
    } else {  
        adapter.reflushList(mDatas);  
    }  

    // 判断是否已经加载完成  
    if (mDatas == null || mDatas.size() <= 0) {  
        reflashFooterView(ConstantUtil.LOAD_MORE_HIDDEN);  
    } else if (mDatas.size() < ConstantUtil.PAGE_SIZE || !isAbleLoading) {  
        reflashFooterView(ConstantUtil.LOAD_MORE_COMPLETE);  
    } else {  
        reflashFooterView(ConstantUtil.LOAD_MORE_BEFORE);  
    }  
}  

三、加载更多分析

加载更多有自己的布局,这个布局始终显示在RecyclerView的底部。要想实现这样的效果,可以利用RecyclerView适配器中ItemViewType,设置多种类型显示。当页面加载完mDatas中的数据之后,就进行底部布局显示。

这里要实现两种样式的布局,需要在RecyclerView适配器当中进行设置。

/**  
 * RecyclerView适配器  
 * Created by 邹峰立 on 2017/10/25.  
 */  
public class RvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {  
    public static final int TYPE_ONE = 0, TYPE_FOOT = 1;  
    private ArrayList<RvData> mDatas = new ArrayList<>();  
    private LayoutInflater mInflater;  
    private FooterData footerData;  

    public RvAdapter(Context context, ArrayList<RvData> list, FooterData footerData) {  
        this.mDatas = list;  
        this.footerData = footerData;  
        this.mInflater = LayoutInflater.from(context);  
    }  

    // 刷新全部数据  
    public void reflushData(ArrayList<RvData> list, FooterData footerData) {  
        this.mDatas = list;  
        this.footerData = footerData;  
        this.notifyDataSetChanged();  
    }  

    // 刷新列表数据  
    public void reflushList(ArrayList<RvData> list) {  
        this.mDatas = list;  
        this.notifyDataSetChanged();  
    }  

    // 刷新底部  
    public void reflushFooterData(FooterData footerData) {  
        this.footerData = footerData;  
        this.notifyItemChanged(getItemCount() - 1);  
    }  

    @Override  
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
        RecyclerView.ViewHolder holder = null;  
        switch (viewType) {  
            case TYPE_ONE:  
                holder = new RVHolder(mInflater.inflate(R.layout.activity_main_item, parent, false));  
                break;  
            case TYPE_FOOT:// 底部  
                holder = new FooterHolder(mInflater.inflate(R.layout.layout_footer, parent, false));  
                break;  
        }  
        return holder;  
    }  

    @Override  
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {  
        int viewType = getItemViewType(position);  
        switch (viewType) {  
            case TYPE_ONE:  
                ((RVHolder) holder).bindHolder(mDatas.get(position), position);  
                break;  
            case TYPE_FOOT:// 底部  
                ((FooterHolder) holder).bindHolder(footerData);  
                break;  
        }  
    }  

    @Override  
    public int getItemCount() {  
        return mDatas.size()   (footerData == null ? 0 : 1);  
    }  

    @Override  
    public int getItemViewType(int position) {  
        if (position < mDatas.size())  
            return mDatas.get(position).getType();  
        else  
            return TYPE_FOOT;  
    }  
}  

四、加载更多实现

首先需要在实现类中继承RecyclerViewScrollListener.OnLoadListener,并实现onLoad加载更多方法。

// 设置recyclerView的布局管理器  
recyclerView = (LoadRecyclerView) findViewById(R.id.recyclerview);  
recyclerView.setLayoutManager(new MyLinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));  
recyclerView.setOnLoadListener(this);  

// 加载更多  
@Override  
public void onLoad() {  
    if (mDatas.size() >= ConstantUtil.PAGE_SIZE && isAbleLoading) {  
        // 获取更多数据  
        // 模拟网络加载  
        new Handler().postDelayed(new Runnable() {  
            @Override  
            public void run() {  
                // 加载数据  
                if (mDatas == null)  
                    mDatas = new ArrayList<>();  
                int num = mDatas.size();  
                for (int i = num; i < num   ConstantUtil.PAGE_SIZE; i  ) {  
                    RvData rvData = new RvData();  
                    rvData.setTitle("标题="   i);  
                    rvData.setDesc("描述="   i);  
                    rvData.setType(RvAdapter.TYPE_ONE);  
                    mDatas.add(rvData);  
                }  
                setAdapter();  
            }  
        }, 3000);  

        reflashFooterView(ConstantUtil.LOAD_MORE);  
        swipeLayout.setRefreshing(false);  
    } else {  
        reflashFooterView(ConstantUtil.LOAD_MORE_COMPLETE);  
    }  

}  

最后给出刷新底部布局方法:

// 刷新底部  
private void reflashFooterView(int index) {  
    // 重构底部数据  
    switch (index) {  
        case ConstantUtil.LOAD_MORE_BEFORE:// 加载前/后  
            recyclerView.setLoading(false);  
            footerData.setShowProgressBar(false);  
            footerData.setShowFooter(true);  
            footerData.setTitle(getResources().getString(R.string.load_more_before));  
            break;  
        case ConstantUtil.LOAD_MORE:// 加载中  
            recyclerView.setLoading(false);  
            footerData.setShowProgressBar(true);  
            footerData.setShowFooter(true);  
            footerData.setTitle(getResources().getString(R.string.load_more));  
            break;  
        case ConstantUtil.LOAD_MORE_COMPLETE:// 不允许加载  
            recyclerView.setLoading(false);  
            footerData.setShowProgressBar(false);  
            footerData.setShowFooter(true);  
            footerData.setTitle(getResources().getString(R.string.load_more_complete));  
            break;  
        case ConstantUtil.LOAD_MORE_HIDDEN:// 隐藏  
            recyclerView.setLoading(false);  
            footerData.setShowProgressBar(false);  
            footerData.setShowFooter(false);  
            footerData.setTitle(getResources().getString(R.string.load_more_complete));  
            break;  
    }  
    // 刷新底部  
    if (adapter != null)  
        adapter.reflushFooterData(footerData);  
}  

Github地址
阅读原文


分分快三计划 4

微信公众号:ibooker爱书客

到这里,整个RecyclerView添加下拉刷新和上拉加载的功能就实现了,具体源码:请看github地址: 源码下载.

要想引用recyclerview,需要在build.gradle中引入相应的依赖:

到这里,就实现了下拉刷新的功能,具体的Adapter的实现,分隔线的加入,请看我前面的两篇文章,或者是看后面附带的源码
这样,我们就实现了下拉刷新的功能,下面再来实现上拉加载更多的功能。

加载更多分析

对于RecyclerView而言,要实现加载更多功能,需要利用RecyclerView.OnScrollListener事件。在OnScrollListener事件提供的onScrollStateChanged进行判断并执行加载更多。

判断条件:
1、可见Item的数量大于0。
2、当前处于滚动停止状态。
3、最后一个可见项大于或等于Item的总数(滚动到最底部)。

另外还需要在OnScrollListener事件提供的onScrolled方法中记录滚动的距离和最后一个可见项的位置。这是提供onScrollStateChanged进行判断的依据。

综上分析,可以将RecyclerView.OnScrollListener事件进行封装,并对外提供接口(执行加载更多接口)。

/**  
 * RecyclerView加载更多滚动事件  
 * Created by 邹峰立 on 2017/4/30 0030.  
 */  
public class RecyclerViewScrollListener extends RecyclerView.OnScrollListener {  
    private enum LAYOUT_MANAGER_TYPE {  
        LINEAR,  
        GRID,  
        STAGGERED_GRID  
    }  

    /**  
     * layoutManager的类型(枚举)  
     */  
    private LAYOUT_MANAGER_TYPE layoutManagerType;  

    /**  
     * 最后一个的位置  
     */  
    private int[] lastPositions;  

    /**  
     * 最后一个可见的item的位置  
     */  
    private int lastVisibleItemPosition;  

    /**  
     * 是否正在加载  
     */  
    private boolean isLoadingMore = false;  

    /**  
     * 记录y轴滚动距离(>0代表向下滚动,<0代表向上滚动)  
     */  
    private int dy;  

    private int totalDy = 0;  

    @Override  
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {  
        super.onScrolled(recyclerView, dx, dy);  
        // 记录y轴滚动距离(>0代表向下滚动)  
        this.dy = dy;  
        this.totalDy  = dy;  
        // 获取RecyclerView布局管理器  
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();  
        if (layoutManagerType == null) {  
            if (layoutManager instanceof LinearLayoutManager) {  
                layoutManagerType = LAYOUT_MANAGER_TYPE.LINEAR;  
            } else if (layoutManager instanceof GridLayoutManager) {  
                layoutManagerType = LAYOUT_MANAGER_TYPE.GRID;  
            } else if (layoutManager instanceof StaggeredGridLayoutManager) {  
                layoutManagerType = LAYOUT_MANAGER_TYPE.STAGGERED_GRID;  
            } else {  
                throw new RuntimeException("Unsupported LayoutManager used. Valid ones are LinearLayoutManager, GridLayoutManager and StaggeredGridLayoutManager");  
            }  
        }  
        // 最后一个可见的item的位置  
        switch (layoutManagerType) {  
            case LINEAR:  
                lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();  
                break;  
            case GRID:  
                lastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();  
                break;  
            case STAGGERED_GRID:  
                StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;  
                if (lastPositions == null) {  
                    lastPositions = new int[staggeredGridLayoutManager.getSpanCount()];  
                }  
                staggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions);  
                lastVisibleItemPosition = findMax(lastPositions);  
                break;  
        }  

        /**  
         * 设置滚动距离事件  
         */  
        if (onScrollDistanceListener != null) {  
            onScrollDistanceListener.onScrollDistance(totalDy);  
        }  

    }  

    // 滚动状态改变  
    @Override  
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {  
        super.onScrollStateChanged(recyclerView, newState);  
        // 获取RecyclerView布局管理器  
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();  
        // 获取RecyclerView可见Item的数量  
        int visibleItemCount = layoutManager.getChildCount();  
        // 获取RecyclerView总Item的数量  
        int totalItemCount = layoutManager.getItemCount();  
        // 判断是否需要加载更多。1、可见性大于0。2、当前处于滚动停止状态。3、最后一个可见项大于或等于Item的总数(滚动到最底部)  
        if (dy > 0 && visibleItemCount > 0 && newState == RecyclerView.SCROLL_STATE_IDLE && (lastVisibleItemPosition >= totalItemCount - 1)) {  
            /**  
             * 加载更多 事件  
             */  
            if (!isLoadingMore && onLoadListener != null) {  
                onLoadListener.onLoad();  
                isLoadingMore = true;  
            }  
        }  

        /**  
         * 滚动状态改变事件  
         */  
        if (onScrollStateChangedListener != null) {  
            onScrollStateChangedListener.onScrollStateChanged(newState);  
        }  
    }  

    private int findMax(int[] lastPositions) {  
        int max = lastPositions[0];  
        for (int value : lastPositions) {  
            if (value > max) {  
                max = value;  
            }  
        }  
        return max;  
    }  

    public boolean isLoadingMore() {  
        return isLoadingMore;  
    }  

    public void setLoadingMore(boolean loadingMore) {  
        isLoadingMore = loadingMore;  
    }  

    // 加载更多接口  
    public interface OnLoadListener {  
        void onLoad();  
    }  

    private OnLoadListener onLoadListener;  

    public void setOnLoadListener(OnLoadListener onLoadListener) {  
        this.onLoadListener = onLoadListener;  
    }  

    // 滚动距离接口  
    public interface OnScrollDistanceListener {  
        void onScrollDistance(int dy);  
    }  

    private OnScrollDistanceListener onScrollDistanceListener;  

    public void setOnScrollDistanceListener(OnScrollDistanceListener onScrollDistanceListener) {  
        this.onScrollDistanceListener = onScrollDistanceListener;  
    }  

    // 滚动状态改变接口  
    public interface OnScrollStateChangedListener {  
        void onScrollStateChanged(int newState);  
    }  

    private OnScrollStateChangedListener onScrollStateChangedListener;  

    public void setOnScrollStateChangedListener(OnScrollStateChangedListener onScrollStateChangedListener) {  
        this.onScrollStateChangedListener = onScrollStateChangedListener;  
    }  
}  

最后对RecyclerView进行再次封装,并实现加载更多相关功能。

/**  
 * 下拉加载更多RecyclerView  
 * Created by 邹峰立 on 2017/10/25.  
 */  
public class LoadRecyclerView extends RecyclerView {  
    private RecyclerViewScrollListener rvScrollListener;  

    public LoadRecyclerView(Context context) {  
        this(context, null);  
    }  

    public LoadRecyclerView(Context context, @Nullable AttributeSet attrs) {  
        this(context, attrs, 0);  
    }  

    public LoadRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {  
        super(context, attrs, defStyle);  
        init();  
    }  

    // 初始化方法  
    private void init() {  
        rvScrollListener = new RecyclerViewScrollListener();  
        this.addOnScrollListener(rvScrollListener);  
    }  

    // 设置是否加载更多  
    public void setLoading(boolean bool) {  
        rvScrollListener.setLoadingMore(bool);  
    }  

    // 加载更多  
    public void setOnLoadListener(RecyclerViewScrollListener.OnLoadListener onLoadListener) {  
        if (rvScrollListener != null)  
            rvScrollListener.setOnLoadListener(onLoadListener);  
    }  
}  
<android.support.v4.widget.SwipeRefreshLayout
 android:id="@ id/layout_swipe_refresh"
 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.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>

下拉刷新分析

下拉刷新是指当布局下拉到顶部的时,要对该界面或者数据进行刷新。一般在下拉刷新时,会有相应的进度条等效果显示。RecyclerView不像ListView那样可以直接添加Header,通过操作Header来实现下拉刷新的效果。但是可以通过RecyclerView的父控件,在父控件中添加相应的下拉刷新的效果。

基于Android Material Design,可以使用SwipeRefreshLayout实现RecyclerView的下拉刷新。

SwipeRefreshLayout使用起来有一个小缺陷,就是无法直接实现下拉刷新效果,只能手动下拉之后才能显示下拉刷新的效果,为了解决这个问题需要对SwipeRefreshLayout进行一些小的修改。这里通过继承SwipeRefreshLayout,添加自动刷新方法autoRefresh,动态修改和调用SwipeRefreshLayout相关属性或方法。

/**  
 * 自定义自动下拉刷新SwipeRefreshLayout  
 * Created by 邹峰立 on 2017/5/10.  
 */  
public class AutoSwipeRefreshLayout extends SwipeRefreshLayout {  
    public AutoSwipeRefreshLayout(Context context) {  
        super(context);  
    }  

    public AutoSwipeRefreshLayout(Context context, AttributeSet attrs) {  
        super(context, attrs);  
    }  

    /**  
     * 自动刷新  
     */  
    public void autoRefresh() {  
        try {  
            Field mCircleView = SwipeRefreshLayout.class.getDeclaredField("mCircleView");  
            mCircleView.setAccessible(true);  
            View progress = (View) mCircleView.get(this);  
            progress.setVisibility(VISIBLE);  

            Method setRefreshing = SwipeRefreshLayout.class.getDeclaredMethod("setRefreshing", boolean.class, boolean.class);  
            setRefreshing.setAccessible(true);  
            setRefreshing.invoke(this, true, true);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}  

在主布局中的文件:加入以下代码:

RecyclerView这是用来显示列表数据,但是不具备下拉刷新和加载更多功能。那么如何去实现这些功能呢?

上拉加载更多效果图

compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'  

监听器已经弄好了,接下来,我们就是在Activity中为RecyclerView添加这个监听器,实现抽象方法onLoadMore()这样就可以了。下面看主要代码:

就是SwipeRefreshLayout中包含我们的recyclerView

从上面的继承结构可以看出, 它继承于:ViewGroup. 而我们常见的LinearLayout, GridLayout等常见的布局,也是继承于ViewGroup。所以它的使用方法和我们常见的差不多,我们想要刷新下拉刷新我们的RecyclerView, 那我们就要将我们的RecyclerView布局文件放到SwipeLayout中。

上面的程序中loadMoreData()方法为:

先不多说,先看效果图:

直接通过代码来理解,代码上也有比较详细的解析

分分快三计划 5

1.创建一个SwipeRefreshLayout对象,在onCreate()方法中初始化
mRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.layout_swipe_refresh);
2.为其添加SwipeRefreshLayout.OnRefreshListener事件:

下拉刷新效果图

您可能感兴趣的文章:

  • Android实现上拉加载更多以及下拉刷新功能(ListView)
  • Android RecyclerView 上拉加载更多及下拉刷新功能的实现方法
  • Android ListView实现上拉加载更多和下拉刷新功能
  • Android下拉刷新上拉加载更多左滑动删除
  • Android XListView下拉刷新和上拉加载更多
  • Android RecyclerView实现下拉刷新和上拉加载更多
  • Android 仿硅谷新闻下拉刷新/上拉加载更多
  • Android中Listview下拉刷新和上拉加载更多的多种实现方案
  • android使用PullToRefresh框架实现ListView下拉刷新上拉加载更多
  • Android实践之带加载效果的下拉刷新上拉加载更多

而在SwipeRefleshLayout中,它又提供了一个接口:SwipeRefreshLayout.OnRefreshListener, 并且在这个口里面提供了一个抽象方法:onRefresh(), 到这里, 我们大概知道它是怎么运作的了,我们只需要在Activity中,实现这个接口,并且实现OnRefresh()方法即可,在onReflesh()方法中,进行我们的刷新数据操作,下面直接来看主要代码:

上拉加载,主要实现的是一个类似分页的功能,不能一开始的时候就加载全部数据,如果数据很多,或者是网络速度慢的话,这需要很久的时间才能加载完成。而上拉加载的思想是:我一开始的时候,就给你加载二十条数据左右,如果你还想看下面的数据的画,再次进行加载二十条,分批次加载,这样就提升了用户体验。

分分快三计划 6

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

一. 实现下拉刷新
在google的android.support.v4包中,提供一个SwipeRefreshLayout方法, 用于实现下拉刷新,实现的过程也非常简单, 那我们先来看一下SwipeRefreshLayout是什么东西,其实从名字上来看,它就是一个刷新布局,我们来看它的继承结构图:

分分快三计划 7

实现以下核心代码:

package com.study.wnw.recyclerviewrefresh;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;

/** * Created by wnw on 16-5-26. */
public abstract class EndLessOnScrollListener extends RecyclerView.OnScrollListener{

 //声明一个LinearLayoutManager
 private LinearLayoutManager mLinearLayoutManager;

 //当前页,从0开始 private int currentPage = 0;
 //已经加载出来的Item的数量
 private int totalItemCount;

 //主要用来存储上一个totalItemCount
 private int previousTotal = 0;

 //在屏幕上可见的item数量
 private int visibleItemCount;

 //在屏幕可见的Item中的第一个
 private int firstVisibleItem;

 //是否正在上拉数据
 private boolean loading = true;

 public EndLessOnScrollListener(LinearLayoutManager linearLayoutManager) {
 this.mLinearLayoutManager = linearLayoutManager;
 }

 @Override
 public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
 super.onScrolled(recyclerView, dx, dy); 

 visibleItemCount = recyclerView.getChildCount();
 totalItemCount = mLinearLayoutManager.getItemCount();
 firstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition();
 if(loading){
  //Log.d("wnwn","firstVisibleItem: "  firstVisibleItem);
  //Log.d("wnwn","totalPageCount:"  totalItemCount); 
  //Log.d("wnwn", "visibleItemCount:"   visibleItemCount);

  if(totalItemCount > previousTotal){
  //说明数据已经加载结束
  loading = false;
  previousTotal = totalItemCount;
  } 
 }
 //这里需要好好理解
 if (!loading && totalItemCount-visibleItemCount <= firstVisibleItem){
  currentPage   ;
  onLoadMore(currentPage);
  loading = true;
 }
 }

 /**
 * 提供一个抽闲方法,在Activity中监听到这个EndLessOnScrollListener
 * 并且实现这个方法
 * */
 public abstract void onLoadMore(int currentPage);}

下面在RecyclerView中,提供了另外一个监听接口:RecyclerView.OnScrollListener
我们可以通过这个接口来创建我们上拉加载更多的功能。

mRecyclerView.addOnScrollListener(new EndLessOnScrollListener(mLinearLayoutManager) {
 @Override
 public void onLoadMore(int currentPage) {
 loadMoreData();
 }
});

在上面的代码中,需要注意的就是理解:visibleItemCount, totalItemCount, firstVisibleItem这几个单词的意思, 在代码里看解析,如果看不懂,可以在程序内打Log,滑动屏幕,看Log, 这样来理解比较好理解

在Activity中

图片来自于网络

SwipeRefreshLayout的继承结构图

今天终于有点时间,来写了一下: 为RecyclerView实现下拉刷新和上拉加载更多。今天会在前面的两篇文章的基础上:
RecyclerView系列之(1):为RecyclerView添加Header和Footer
RecyclerView系列之(2):为RecyclerView添加分隔线
继续讲述RecyclerView中一些常用组件的实现下拉刷新和上拉加载更多的功能。
在现在的Android手机应用中,几乎每一个APP都有下拉刷新和上拉加载更多的功能,它们的重要性不言而喻。

到这里,我们的整个RecyclerView系列之(3)就实现了, 这三篇文章,它能做到的,ListView都可以做到,并没有体现出RecyclerView的灵活性,关于RecyclerView的灵活性, 很多人会想到一个词:瀑布流,看下图

//每次上拉加载的时候,给RecyclerView的后面添加了10条数据数据
private void loadMoreData(){
 for (int i =0; i < 10; i  ){
 mData.add("嘿,我是“上拉加载”生出来的" i);
 mAdapter.notifyDataSetChanged();
 }
}

而下一篇文章我会带来RecyclerView瀑布流的实现,谢谢咯。

二. 上拉加载更多

本文由分分快三计划发布,转载请注明来源

关键词: 分分快三计划 Android笔记 书客创作[ib...