自Android5.0出来,大家可能对RecyclerView不陌生了,可是在实际项目中却不敢用,因为不熟悉,
也不会像ListView那样有很多库支持,比如PullToRefreshListiew
现在我们就仿照来自定义PullToRefreshRecyclerView
我们不着急,先看看源代码的上下拉是怎么判断的吧
带着你们找找源码吧,去类库里找到上下拉的基类
PullToRefreshBase
下面重写的代码就是判断上下拉刷新的
isReadyForPullStart 控件是否到顶
isReadyForPullEnd 控件是否到底
@Override public final boolean demo() { if (mMode.showHeaderLoadingLayout() && isReadyForPullStart()) { smoothScrollToAndBack(-getHeaderSize() * 2); return true; } else if (mMode.showFooterLoadingLayout() && isReadyForPullEnd()) { smoothScrollToAndBack(getFooterSize() * 2); return true; } return false; }
我们需要找到这两个方法是如何写的,去参照PullToRefreshListiew类吧
ctrl+f,找到这两个方法,没有找到,那我们就从继承的类里找
public class PullToRefreshListView extends PullToRefreshAdapterViewBase<ListView> 进入到PullToRefreshAdapterViewBase类中
ctrl+fprotected boolean isReadyForPullEnd() { return isLastItemVisible(); }进入isLastItemVisible()方法如下private boolean isLastItemVisible() { final Adapter adapter = mRefreshableView.getAdapter();//获取adapter if (null == adapter || adapter.isEmpty()) { if (DEBUG) { Log.d(LOG_TAG, "isLastItemVisible. Empty View."); } return true; } else { final int lastItemPosition = mRefreshableView.getCount() - 1;//找到最后一个元素对应的位置 final int lastVisiblePosition = mRefreshableView.getLastVisiblePosition();//最后一个可见元素 对应的位置 if (lastVisiblePosition >= lastItemPosition - 1) { final int childIndex = lastVisiblePosition - mRefreshableView.getFirstVisiblePosition(); final View lastVisibleChild = mRefreshableView.getChildAt(childIndex); if (lastVisibleChild != null) { return lastVisibleChild.getBottom() <= mRefreshableView.getBottom();//这是关键代码, //如果可见元素的y坐标小于等于整个空间的y坐标,就是到了最后一个元素了 } } } return false; }
大家可能想,mRefreshableView这个变量哪里来的?不着急,我们后面会写到,同理另一个方法,我直接贴上,就不用解释了private boolean isFirstItemVisible() { final Adapter adapter = mRefreshableView.getAdapter(); if (null == adapter || adapter.isEmpty()) { return true; } else { if (mRefreshableView.getFirstVisiblePosition() <= 1) { final View firstVisibleChild = mRefreshableView.getChildAt(0); if (firstVisibleChild != null) { return firstVisibleChild.getTop() >= mRefreshableView.getTop(); } } } return false; } 好啦,方法看见了,我们直接自定义吧package b2a.main.widget.RecycleRelating; import android.content.Context; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.widget.Adapter; import com.handmark.pulltorefresh.library.PullToRefreshBase; import b2a.main.R; /** * Created by shf on 2015/7/23. */ public class PullToRefreshRecyclerView extends PullToRefreshBase<RecyclerView> { public PullToRefreshRecyclerView(Context context) { super(context); } public PullToRefreshRecyclerView(Context context, AttributeSet attrs) { super(context, attrs); } public PullToRefreshRecyclerView(Context context, Mode mode) { super(context, mode); } public PullToRefreshRecyclerView(Context context, Mode mode, AnimationStyle animStyle) { super(context, mode, animStyle); } /** * 刷新的方向 * * @return */ @Override public Orientation getPullToRefreshScrollDirection() { return Orientation.VERTICAL; } /** * 创建刷新内容 * * @param context Context to create view with * @param attrs AttributeSet from wrapped class. Means that anything you * include in the XML layout declaration will be routed to the * created View * @return */ @Override protected RecyclerView createRefreshableView(Context context, AttributeSet attrs) { RecyclerView recycler = new RecyclerView(context, attrs); recycler.setId(R.id.recyclerSHF);//在资源文件中配置ids return recycler; } /** * 控件是否到底 * * @return */ @Override protected boolean isReadyForPullEnd() { RecyclerView recycler = getRefreshableView();//获取刷新的view final RecyclerView.Adapter adapter = recycler.getAdapter(); if (null == adapter || adapter.getItemCount() == 0) { Log.i("SHF", "因为没有数据控件到底了-->001-->" + adapter.getItemCount()); return true; } else { final int lastItemPosition = adapter.getItemCount() - 1; final int lastVisiblePosition = ((LinearLayoutManager) recycler.getLayoutManager()). findLastVisibleItemPosition(); Log.i("SHF", "lastItemPosition-->" + lastItemPosition + "lastVisiblePosition-->" + lastVisiblePosition); if (lastVisiblePosition >= lastItemPosition - 1) { final int childIndex = lastVisiblePosition - ((LinearLayoutManager) recycler.getLayoutManager()).findFirstVisibleItemPosition(); final View lastVisibleChild = recycler.getChildAt(childIndex); if (lastVisibleChild != null) { Log.i("SHF", "因为数据控件到底了-->002"); return lastVisibleChild.getBottom() <= recycler.getBottom(); } } } Log.i("SHF", "因为数据控件没到底-->003"); return false; } @Override protected boolean isReadyForPullStart() { RecyclerView recycler = getRefreshableView();//获取刷新的view final RecyclerView.Adapter adapter = recycler.getAdapter(); if (null == adapter || adapter.getItemCount() == 0) { return true; } else { if (((LinearLayoutManager) recycler.getLayoutManager()).findFirstVisibleItemPosition() <= 1) { final View firstVisibleChild = recycler.getChildAt(0); if (firstVisibleChild != null) { return firstVisibleChild.getTop() >= recycler.getTop(); } } } return false; } }参照listview我们也写好那两个判断方法即可,这里要提两个地方,
一个是RecyclerView recycler = getRefreshableView();//获取刷新的view
这就是获取控件,上面已经提到啦
另一个是recycler.setId(R.id.recyclerSHF);//在资源文件中配置ids
这里大家依照我写的配置一下就行了
res-->values-->ids.xml 没有的话新建一个<?xml version="1.0" encoding="utf-8"?> <resources> <item type="id" name="gridview" /> <item type="id" name="webview" /> <item type="id" name="scrollview" /> </resources> 大功告成,放心大胆的用吧