RecycleView下拉刷新控件的封装(包括下拉刷新和加载更多 )
来源:互联网 发布:重庆移动网络加速器 编辑:程序博客网 时间:2024/05/19 15:44
最近学习了RecycleView控件的使用,就尝试封装了RecycleView 下拉刷新控件,实现的功能有(下拉刷新和加载更多)
转载请注明原博客地址:http://blog.csdn.net/gdutxiaoxu/article/details/51473358
1 思路解析
1)我是通过继承LinearLayout来实现的,里面拥有SwipeRefreshLayout和RecycleView
2)下拉刷新是通过SwipeRefreshLayout设置监听器实现的
mSwipeRfl.setOnRefreshListener(mRefreshListener);
3)加载更多是通过监听RecycleView的OnScrollListener
mScrollListener = new RecyclerView.OnScrollListener() { private int mLastVisibleItem; private int mDy; @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState != RecyclerView.SCROLL_STATE_IDLE) { return; } //最后显示的项 mLastVisibleItem = mLayoutManager.findLastCompletelyVisibleItemPosition(); int totalItemCount = mLayoutManager.getItemCount(); /** * 只有在下拉,并且没有早加载更多,并且允许加载更多,并且在最后一个条目,才调用加载更多的接口 */ if (mDy >= 0 && !isLoadMore && (mLastVisibleItem >= totalItemCount - 1) && enableLoadMore) { loadMore(); } }
2 下面给出源码
public class PulltoRefreshRecyclerView extends LinearLayout { String Tag = "xujun"; /** * 内容控件 */ private RecyclerView mRecyclerView; /** * 刷新布局控件 */ private SwipeRefreshLayout mSwipeRfl; private LinearLayoutManager mLayoutManager; /* * 刷新布局的监听 */ private OnRefreshListener mRefreshListener; /** * 内容控件滚动监听 */ private RecyclerView.OnScrollListener mScrollListener; /* * 刷新加载监听事件 */ private onRefreshListener mRefreshLoadMoreListner; /** * 是否正在刷新 */ private boolean isRefresh = false; /** * 是否正在加载更多 */ private boolean isLoadMore = false; private FrameLayout mFootView; // 是否允许加载更多 private boolean enableLoadMore = true; private int mMeasuredHeight; public PulltoRefreshRecyclerView(Context context) { this(context, null); } @SuppressWarnings("deprecation") public PulltoRefreshRecyclerView(Context context, AttributeSet attrs) { super(context, attrs); // 导入布局 initView(context); /** * 监听上拉至底部滚动监听 */ initListener(); mRecyclerView.setHasFixedSize(true); mLayoutManager = new LinearLayoutManager(context); mRecyclerView.setLayoutManager(mLayoutManager); mRecyclerView.setOnScrollListener(mScrollListener); } private void setFootViewHeight(int height) { ViewGroup.LayoutParams layoutParams = mFootView.getLayoutParams(); layoutParams.height = height; mFootView.setLayoutParams(layoutParams); } private void initListener() { mScrollListener = new RecyclerView.OnScrollListener() { private int mLastVisibleItem; private int mDy; @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState != RecyclerView.SCROLL_STATE_IDLE) { return; } //最后显示的项 mLastVisibleItem = mLayoutManager.findLastCompletelyVisibleItemPosition(); int totalItemCount = mLayoutManager.getItemCount(); /** * 只有在下拉,并且没有早加载更多,并且允许加载更多,并且在最后一个条目,才调用加载更多的接口 */ if (mDy >= 0 && !isLoadMore && (mLastVisibleItem >= totalItemCount - 1) && enableLoadMore) { loadMore(); } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); mDy = dy; } }; /** * 下拉至顶部刷新监听 */ mRefreshListener = new OnRefreshListener() { @Override public void onRefresh() { /* Log.i("Tag", "onRefresh1"); Log.i("Tag", isRefresh + ""); Log.i("Tag", isRefresh + ""); Log.i("Tag", isLoadMore + "");*/ LUtils.i("isLoadMore=" + isLoadMore); if (!isRefresh && !isLoadMore) {//没有正在刷新或者正在加载更多 isRefresh = true; refresh(); } } }; mSwipeRfl.setOnRefreshListener(mRefreshListener); } private void initView(Context context) { View.inflate(context, R.layout.pulltorefreshrecyclerview,this); mSwipeRfl = (SwipeRefreshLayout) findViewById(R.id.all_swipe); mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view); initFootView(); } private void initFootView() { mFootView = (FrameLayout) findViewById(R.id.ll_load_more); LUtils.i("mFootView=" +(mFootView==null)); mFootView.measure(0, 0); mMeasuredHeight = mFootView.getMeasuredHeight(); setFootViewHeight(0); } public void setFooterView(View view) { if (getFooterView() != null) { getFooterView().removeAllViews(); mFootView.addView(view); } } public FrameLayout getFooterView() { return mFootView; } public RecyclerView getRecyclerView() { return mRecyclerView; } public void setLayoutManager(LayoutManager layoutManager) { if (mRecyclerView != null) { mRecyclerView.setLayoutManager(layoutManager); } } /** * 设置是否允许下拉刷新 * * @param enable */ public void setPullRefreshEnable(boolean enable) { setRefreshEnabled(enable); } public boolean getPullRefreshEnable() { return mSwipeRfl.isEnabled(); } public void setLoadMoreListener() { mRecyclerView.setOnScrollListener(mScrollListener); } public void loadMore() { if (mRefreshLoadMoreListner != null) { isLoadMore = true; //设置在加载更多的时候swipeLayout不允许加载更多,同时需要设置在加载更多完毕的时候允许swipeLayout加载更多 setRefreshEnabled(false); mLayoutManager.scrollToPosition(mLayoutManager.findLastVisibleItemPosition()); showFootView(); mRefreshLoadMoreListner.onLoadMore(mRecyclerView); } } public void setRefreshEnabled(boolean enabled) { mSwipeRfl.setEnabled(enabled); } private void showFootView() { setFootViewHeight(mMeasuredHeight); } public void OnRefreshCompleted() { if (isRefresh) {//如果是正在刷新,就调用这个方法 stopRefresh(); } else if (isLoadMore) {//如果是正在加载更多,就调用这个方法 setLoadMoreCompleted(); } } /** * 加载更多完毕,为防止频繁网络请求,isLoadMore为false才可再次请求更多数据 */ private void setLoadMoreCompleted() {//因为在加载更多的时候设置swipeLayout不允刷新,// 所以加载更多完毕的时候需要设置允许swipeLayout允许刷新 setRefreshEnabled(true); isLoadMore = false; hideFootView(); } private void hideFootView() {// setFootViewHeight(0); rollbackFootView(mFootView); } private void stopRefresh() { isRefresh = false; mSwipeRfl.setRefreshing(false); } public void setOnRefreshListener(onRefreshListener listener) { mRefreshLoadMoreListner = listener; } public void refresh() { if (mRefreshLoadMoreListner != null) { mRefreshLoadMoreListner.onRefresh(mRecyclerView); } } public void setAdapter(RecyclerView.Adapter adapter) { if (adapter != null) mRecyclerView.setAdapter(adapter); } public interface onRefreshListener { public void onRefresh(RecyclerView recyclerView); public void onLoadMore(RecyclerView recyclerView); } /** * 回滚下拉刷新头部控件 */ private void rollbackFootView(View view) { final ValueAnimator rbAnimator = ValueAnimator.ofInt(0, mMeasuredHeight); rbAnimator.setDuration(800); rbAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); rbAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float animatedFraction = animation.getAnimatedFraction(); /** * 当刷新完毕后,进行headerView的隐藏 */ setFootViewHeight((int) (mMeasuredHeight - animatedFraction * mMeasuredHeight)); } }); rbAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { rbAnimator.removeAllListeners(); } }); rbAnimator.start(); } public boolean isLoadMore() { return isLoadMore; } public boolean isRefresh() { return isRefresh; } public boolean isEnableLoadMore() { return enableLoadMore; }}
3 存在的问题
1)在判断是够加载更多的时候 需要mLastVisibleItem
/** * 只有在下拉,并且没有早加载更多,并且允许加载更多,并且在最后一个条目,才调用加载更多的接口 */if (mDy >= 0 && !isLoadMore && (mLastVisibleItem >= totalItemCount - 1) && enableLoadMore) { loadMore();}
//最后显示的项mLastVisibleItem = mLayoutManager.findLastCompletelyVisibleItemPosition();但是findLastCompletelyVisibleItemPosition()这个方法是LinearLayoutManger里面的 方法 ,LinearLayoutManger的父类里面 RecyclerView.LayoutManager没有这个方法findLastCompletelyVisibleItemPosition();这样导致我们 无法动态更改我们当前RecycleView实例的 LayoutManger
2)暂时没有实现SwipeLayoutProgress下拉刷新显示进度条 离我们第一个item之间的距离,可以参考http://www.cnblogs.com/sunzn/p/3795009.html
3)暂时没有实现自定义属性,使用起来没有那么方便
4)源码下载地址:https://github.com/gdutxiaoxu/RecycleViewDemo 0 0
- RecycleView下拉刷新控件的封装(包括下拉刷新和加载更多 )
- 自己封装的工具类,使用原生SwipeRefreshLayout+RecycleView实现下拉刷新和加载更多
- RecycleView从显示到下拉刷新和加载更多
- SwipeRefreshLayout +RecycleView实现上拉加载更多和下拉刷新
- 轻松实现RecycleView的下拉刷新、加载更多
- RecycleView控件的使用(三) 实现上拉加载更多下拉刷新功能
- 下拉刷新和加载更多
- 支持任意View下拉刷新/下拉加载更多的控件
- 【recyclerview封装】recycleview上拉加载 下拉刷新,加载更多,适配器全面封装。
- 下拉刷新--加载更多
- RecyclerView封装--添加下拉刷新和上拉加载更多
- RecycleView上拉加载和下拉刷新
- Android自定义控件下拉刷新和加载更多
- Android之RecycleView下拉刷新上滑加载更多
- RecycleView添加下拉刷新、上拉加载更多
- RecycleView的上啦加载下拉刷新
- 自定义下拉刷新和上拉加载的recycleview
- 下拉刷新和上拉加载更多
- SI4463模块使用心得(无线协议)
- 为什么运行delphi时菜单栏没有显示,但是设计时菜单栏出现?
- ORA-12514问题解决
- Hibernate与 MyBatis的比较
- GG 单实例10g 到 11g RAC 搭建配置
- RecycleView下拉刷新控件的封装(包括下拉刷新和加载更多 )
- C#利用 Face++sdk 实现wpf小程序【2】 5/11/22
- Openwrt编译:root.squashfs-64k is too big (Max=6488064 , Current=xxxx)
- sky_Move Zeroes
- 在mac系统安装eclipse与配置
- Resources$NotFoundException
- Android中在子线程中更新UI的两种方式
- GG搭建 源单实例---到目标RAC环境 11.2.3版本 单向同步(XX公司项目)
- c中的主要关键字