换一种思路--使用behavior实现recyclerView的下拉加载更多
2017-04-20 10:25
507 查看
下面是整体效果图,虽然很简单,不过功能还是是完善的。。。。
Android 5.0退出 MD风格之后,到现在可以看到很多应用都用上了各种材料设计风格,其中recyclerView应该在很大程度上已经取代了listView,而我们以前常用的上啦刷新和下拉加载也就在所有应用上都成了必不可少的一部分了,下拉刷新我们就不说了 ,毕竟谷歌已经提供了SwipeRefreshLayout。那么我们就来聊聊下拉加载吧.
1.网上大部分实现的方案都是下面这样的:
这里就不多做介绍了,实现方式和listView的实现原理差不多,通过最后一个可见item的position和item的总数来判断是不是到了最后一个item了。
2.我们今天来实现的方式呢略有一点不一样,首先你可能需要有点CoordinatorLayout和behavior的知识,如果你这块还不是很懂的话可以看看http://blog.csdn.net/yanzhenjie1003/article/details/52205665。
那么接下来,我们来看看我们的实现思路,在这之前我想说下就是以下的东西我只是提供了简单的实现想法,在项目中的话,你应该还有更好的封装:
第一步:我们自定义一个ViewGroup用来响应我们的behavior(踩坑:建议直接继承ViewGroup来自定义,因为其实我们的加载更多布局是隐藏在屏幕下方的,而不是一个recyclerView的item,那么这时候当你继承linearlayout的时候,隐藏在下方没有出现的布局将被裁剪掉,然后你就发现我们的加载更多不见了)
第二步 好了,我们来看看我们behavior是怎么写的吧:
好吧,这篇博文主要还是想写一个思路,过多的也不说了,希望这篇文章对你有帮助,这是完整的demo链接
Android 5.0退出 MD风格之后,到现在可以看到很多应用都用上了各种材料设计风格,其中recyclerView应该在很大程度上已经取代了listView,而我们以前常用的上啦刷新和下拉加载也就在所有应用上都成了必不可少的一部分了,下拉刷新我们就不说了 ,毕竟谷歌已经提供了SwipeRefreshLayout。那么我们就来聊聊下拉加载吧.
1.网上大部分实现的方案都是下面这样的:
mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState == RecyclerView.SCROLL_STATE_IDLE && lastVisibleItem + 1 == adapter.getItemCount()) { mSwipeRefreshWidget.setRefreshing(true); handler.sendEmptyMessageDelayed(0, 3000); } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); lastVisibleItem = mLayoutManager.findLastVisibleItemPosition(); } });
这里就不多做介绍了,实现方式和listView的实现原理差不多,通过最后一个可见item的position和item的总数来判断是不是到了最后一个item了。
2.我们今天来实现的方式呢略有一点不一样,首先你可能需要有点CoordinatorLayout和behavior的知识,如果你这块还不是很懂的话可以看看http://blog.csdn.net/yanzhenjie1003/article/details/52205665。
那么接下来,我们来看看我们的实现思路,在这之前我想说下就是以下的东西我只是提供了简单的实现想法,在项目中的话,你应该还有更好的封装:
第一步:我们自定义一个ViewGroup用来响应我们的behavior(踩坑:建议直接继承ViewGroup来自定义,因为其实我们的加载更多布局是隐藏在屏幕下方的,而不是一个recyclerView的item,那么这时候当你继承linearlayout的时候,隐藏在下方没有出现的布局将被裁剪掉,然后你就发现我们的加载更多不见了)
@CoordinatorLayout.DefaultBehavior(LoadMore.class)//**这个就是关联到我们自定义的behavior** public class LoadMoreLayout extends ViewGroup { private FrameLayout mBottomView; private IStartLoad mStartLoad; public LoadMoreLayout(Context context) { this(context, null); } public LoadMoreLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public LoadMoreLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mBottomView = new FrameLayout(getContext()); } //自定义测量。。。 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int hei = 0; for (int i = 0; i < getChildCount(); i++) { View childAt = getChildAt(i); measureChild(childAt, widthMeasureSpec, heightMeasureSpec); hei += childAt.getMeasuredHeight(); } setMeasuredDimension(getDefaultSize(widthMeasureSpec, 0), hei); } //布局,从上往下排列(这也意味着我们的 recyclerView应该是在第一个布局的,不够完善,请根据自己需求来重写) @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { for (int i = 0; i < getChildCount(); i++) { View childAt = getChildAt(i); View pre = getPreChild(i - 1); if (pre == null) { childAt.layout(0, 0, r, childAt.getMeasuredHeight()); } else { childAt.layout(0, pre.getBottom(), r, pre.getBottom() + childAt.getMeasuredHeight()); } } } @Override protected void onFinishInflate() { super.onFinishInflate(); addView(mBottomView);//将我们的底部加载更多布局添加进来 } private View getPreChild(int i) { if (i < 0) { return null; } else { return getChildAt(i); } } public void setBottomView(View view){ mBottomView.addView(view);//我们可以自定义 加载更多布局 传进来 } public int getBottomHeight() { return mBottomView.getHeight(); } public void startLoad() { if(mStartLoad!=null){ mStartLoad.startLoad();//开始加载更多的回调 } } public void reset() { scrollBy(0, -getScrollY());//其实这就是简单的隐藏加载更多布局 } public IStartLoad getStartLoad() { return mStartLoad; } public void setStartLoad(IStartLoad mStartLoad) { this.mStartLoad = mStartLoad; } public interface IStartLoad { void startLoad(); }
第二步 好了,我们来看看我们behavior是怎么写的吧:
import android.support.design.widget.CoordinatorLayout; import android.view.View; /** * create by liuhuang at 2017/4/19 */ public class LoadMore extends CoordinatorLayout.Behavior { //这应该就是一个很简单的behavior了,也没什么好说的 ,如果不懂的话可以先去度娘问问behavior的实现 //我们这里的整体思路也是当recyclerView滑动到最底部的时候, //去scroll我们的LoadMoreLayout来显示加载更多的布局 @Override public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) { return child instanceof LoadMoreLayout; } @Override public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) { int scrollY = child.getScrollY(); // System.out.println("=="+scrollY+"=="+dy); if (scrollY > 0 && dy < 0) { int canScrollY = getCanScrollY(scrollY, dy); child.scrollBy(0, -canScrollY); consumed[1] = canScrollY; } else if (scrollY < 0 && dy > 0) { int canScrollY = getCanScrollY(scrollY, dy); child.scrollBy(0, canScrollY); consumed[1] = canScrollY; } } @Override public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) { // System.out.println(dyConsumed + "===" + dyUnconsumed); if (dyConsumed == 0 && dyUnconsumed > 0) { //滑到底部了 if (child instanceof LoadMoreLayout) { LoadMoreLayout layout = (LoadMoreLayout) child; int scrollY = child.getScrollY(); int max = layout.getBottomHeight() - scrollY; int canScrollY = getCanScrollY(max, dyUnconsumed); child.scrollBy(0, canScrollY); if (canScrollY != 0) { layout.startLoad(); } } } } private int getCanScrollY(int needY, int provideY) { int absNeedY = Math.abs(needY); int absProvideY = Math.abs(provideY); if (absProvideY >= absNeedY) { return absNeedY; } else { return absProvideY; } } }
好吧,这篇博文主要还是想写一个思路,过多的也不说了,希望这篇文章对你有帮助,这是完整的demo链接
相关文章推荐
- 在Android Studio上使用GSON+VOLLEY,秒处理网络数据成集合。感受框架的力量。搭配RecyclerView和SwipeRefreshLayout,实现底端加载更多,下拉刷新。
- Android使用RecyclerView实现上拉加载更多,下拉刷新,分组显示
- 使用SwipeRefreshLayout和RecyclerView实现仿“简书”下拉刷新和上拉加载更多
- RecyclerView 上拉加载更多下拉刷新的一种实现
- 使用SwipeRefreshLayout和RecyclerView实现仿“简书”下拉刷新和上拉加载更多
- 使用SwipeRefreshLayout和RecyclerView实现仿“简书”下拉刷新和上拉加载更多
- 使用SwipeRefreshLayout和RecyclerView实现仿“简书”下拉刷新和上拉加载更多
- 使用SwipeRefreshLayout和RecyclerView实现下拉刷新上拉加载更多
- 微信小程序,使用scroll-view实现下拉加载更多(下一页)源码
- 使用SwipeRefreshLayout和RecyclerView实现仿“简书”下拉刷新和上拉加载更多
- Android中Recyclerview使用13----实现瀑布流遇到的各种问题(item移动,加载更多图片闪烁,以及定制各种类型Header和Footer)
- ListView、RecyclerView 两种方式实现聊天界面支持文字、表情、图片和语音信息,支持下拉加载更多
- 使用RecyclerView 和SwipeRefreshLayout实现上拉加载更多功能
- 使用SwipeRefreshLayout和RecyclerView实现下拉刷新上拉加载更多
- 使用SwipeRefreshLayout和RecyclerView实现仿“简书”下拉刷新和上拉加载更多
- RecycleView控件的使用(三) 实现上拉加载更多下拉刷新功能
- Android RecyclerView 加载更多数据 及 不同类型itemView的使用
- RecyclerView之下拉刷新、下拉加载的实现
- 封装RecyclerViewAdapter实现RecyclerView下拉刷新上拉加载更多
- RecyclerView配合SwipeRefreshLayout实现下拉刷新以及实现上拉加载更多