支持上下拉刷新的RecycleView,基于androidPullToRefresh,添加RecycleView HeaderView
2017-04-20 10:20
537 查看
如题,基于android PullToRefresh的支持上拉刷新下拉加载的RecycleView
直接上码:
RecycleView的使用:
Adapter:
分割线实现:
计算滑动距离
参考博客:
http://blog.csdn.net/mr_wanggang/article/details/46707441
http://blog.csdn.net/lmj623565791/article/details/45059587
http://blog.csdn.net/skykingf/article/details/50827141
https://blog.piasy.com/2016/03/26/Insight-Android-RecyclerView-ItemDecoration/
http://blog.csdn.net/guolin_blog/article/details/10470797/
http://apkbus.com/blog-35555-59152.html
http://blog.csdn.net/xuehuayous/article/details/50394640
http://blog.csdn.net/huangxiaoguo1/article/details/53706971
直接上码:
public class PullToRefreshRecycleView extends PullToRefreshBase<RecyclerView> { private OnHeaderRefreshListener<RecyclerView> m_OnHeaderRefreshListener; private OnFooterRefreshListener<RecyclerView> m_OnFooterRefreshListener; private final OnRefreshListener2<RecyclerView> m_OnRefreshListener = new OnRefreshListener2<RecyclerView>() { @Override public void onPullDownToRefresh(PullToRefreshBase<RecyclerView> view) { if (m_OnHeaderRefreshListener != null) { m_OnHeaderRefreshListener.onHeaderRefresh(view); } } @Override public void onPullUpToRefresh(PullToRefreshBase<RecyclerView> view) { if (m_OnFooterRefreshListener != null) { m_OnFooterRefreshListener.onFooterRefresh(view); } } }; @Override protected void onRefreshing(boolean doScroll) { super.onRefreshing(doScroll); if(Mode.PULL_FROM_END == getCurrentMode()){ getFooterLayout().refreshing(); }else if(Mode.PULL_FROM_START == getCurrentMode()){ getHeaderLayout().refreshing(); } } @Override protected void onReleaseToRefresh() { super.onReleaseToRefresh(); inLoad = false; } private RecyclerView view; public PullToRefreshRecycleView(Context context) { super(context); init(); } public PullToRefreshRecycleView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public PullToRefreshRecycleView(Context context, Mode mode) { super(context, mode); init(); } public PullToRefreshRecycleView(Context context, Mode mode, AnimationStyle style) { super(context, mode, style); init(); } private void init(){ setOnRefreshListener(m_OnRefreshListener); } @Override public Orientation getPullToRefreshScrollDirection() { return Orientation.VERTICAL; } @Override protected RecyclerView createRefreshableView(Context context, AttributeSet attrs) { view = new RecyclerView(context, attrs); view.setId(R.id.discovery_recycle_view); return view; } @Override protected boolean isReadyForPullEnd() { View view = getRefreshableView().getChildAt(getRefreshableView().getChildCount() - 1); if (null != view) { return getRefreshableView().getBottom() >= view.getBottom() - 1; } return false; } @Override protected boolean isReadyForPullStart() { View view = getRefreshableView().getChildAt(0); if (view != null) { return view.getTop() >= getRefreshableView().getTop(); } return false; } @Override public void setOnHeaderRefreshListener(OnHeaderRefreshListener l) { m_OnHeaderRefreshListener = l; } @Override public void setOnFooterRefreshListener(OnFooterRefreshListener l) { m_OnFooterRefreshListener = l; } @Override public void onHeaderRefreshComplete() { onRefreshComplete(); } @Override public void onFooterRefreshComplete() { onRefreshComplete(); } @Override public void setDisableHeaderRefresh(boolean canNot) { if (canNot) { switch (getMode()) { case BOTH: setMode(Mode.PULL_FROM_END); break; case PULL_FROM_START: setMode(Mode.DISABLED); break; } } else { switch (getMode()) { case BOTH: case PULL_FROM_END: setMode(Mode.BOTH); break; default: setMode(Mode.PULL_FROM_START); break; } } } @Override public void setDisableFootRefresh(boolean canNot) { if (canNot) { switch (getMode()) { case BOTH: setMode(Mode.PULL_FROM_START); break; case PULL_FROM_END: setMode(Mode.DISABLED); break; } } else { switch (getMode()) { case BOTH: case PULL_FROM_START: setMode(Mode.BOTH); break; default: setMode(Mode.PULL_FROM_END); break; } } } @Override public void setLastUpdated(CharSequence lastUpdated) { getLoadingLayoutProxy().setLast 4000 UpdatedLabel(lastUpdated); } public void setLayoutManager(RecyclerView.LayoutManager layout) { if (null != view) { view.setLayoutManager(layout); } } public void setAdapter(RecyclerView.Adapter adapter) { if (null != view) { view.setAdapter(adapter); } } public void addItemDecoration(RecyclerView.ItemDecoration decor) { if (null != view) { view.addItemDecoration(decor); } } private int getFirstVisiblePosition() { View firstVisibleChild = getRefreshableView().getChildAt(0); return firstVisibleChild != null ? getRefreshableView() .getChildAdapterPosition(firstVisibleChild) : -1; } private int getLastVisiblePosition() { View lastVisibleChild = getRefreshableView().getChildAt(getRefreshableView() .getChildCount() - 1); return lastVisibleChild != null ? getRefreshableView() .getChildAdapterPosition(lastVisibleChild) : -1; } public void moveToPosition(int n) { int firstItem = getFirstVisiblePosition(); int lastItem = getLastVisiblePosition(); if (n <= firstItem) { getRefreshableView().scrollToPosition(n); } else if (n <= lastItem) { int top = getRefreshableView().getChildAt(n - firstItem).getTop(); getRefreshableView().scrollBy(0, top); } else { getRefreshableView().scrollToPosition(n); } } }
RecycleView的使用:
private PullToRefreshRecycleView discoveryRecycleView; //设置瀑布流的LayoutManager,还可以实现GridView,ListView等 discoveryRecycleView.setLayoutManager(new StaggeredGridLayoutManager(NUM_COLUMNS, StaggeredGridLayoutManager.VERTICAL)); //添加头部View discoveryAdapter.addHeadView(R.layout.refresh_view_header); discoveryRecycleView.setAdapter(discoveryAdapter); //设置分割线样式 discoveryRecycleView.addItemDecoration(new DividerGridItemDecoration(getResources(), R.color.white, R.dimen.discovery_item_divider_size, discoveryRecycleView.getOrientation())); discoveryRecycleView.setDisableHeaderRefresh(false); discoveryRecycleView.setDisableFootRefresh(false); discoveryRecycleView.setOnHeaderRefreshListener(mHeaderRefreshListener); discoveryRecycleView.setOnFooterRefreshListener(mOnFooterRefreshListener);
Adapter:
public class DiscoveryDetailRecycleViewStageredAdapter extends DiscoveryAdapter { private final Logger log = Logger.getLogger(DiscoveryDetailRecycleViewStageredAdapter.class); private static final int TYPE_HEADER = 0, TYPE_ITEM = 1, TYPE_FOOT = 2; public DiscoveryDetailRecycleViewStageredAdapter(Context context, List<DiscoveryItemModel> discoveryList) { super(context, discoveryList); } public void addHeadView(int view) { headViewId = view; headViewSize = 1; isAddHead = true; } public int hasHeadView() { return headViewSize; } public void addFootView(int view) { footViewId = view; footViewSize = 1; isAddFoot = true; } @Override public DiscoveryItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = null; switch (viewType) { case TYPE_HEADER: view = LayoutInflater.from(parent.getContext()).inflate(headViewId, parent, false); break; case TYPE_ITEM: return super.onCreateViewHolder(parent, viewType); case TYPE_FOOT: view = LayoutInflater.from(parent.getContext()).inflate(footViewId, parent, false); break; } return new DiscoveryItemViewHolder(view); } @Override public void onBindViewHolder(DiscoveryItemViewHolder holder, int position) { switch (holder.getItemViewType()) { case TYPE_HEADER: //将头部View 变为横向铺满 StaggeredGridLayoutManager.LayoutParams clp = (StaggeredGridLayoutManager.LayoutParams) holder.cardView.getLayoutParams(); if (clp != null) clp.setFullSpan(true); holder.bindHeader(title, subTitle, coverUrl); break; case TYPE_ITEM: super.onBindViewHolder(holder, position); break; case TYPE_FOOT: StaggeredGridLayoutManager.LayoutParams clp1 = (StaggeredGridLayoutManager.LayoutParams) holder.cardView.getLayoutParams(); clp1.setFullSpan(true); break; } } @Override public int getItemViewType(int position) { int type = TYPE_ITEM; if (headViewSize == 1 && position == 0) { type = TYPE_HEADER; } else if (footViewSize == 1 && position == getItemCount() - 1) { //最后一个位置 type = TYPE_FOOT; } return type; } @Override public int getItemCount() { return discoveryList.size() + headViewSize + footViewSize; } @Override public Object getItem(int position) { position-=headViewSize; return super.getItem(position); } }
分割线实现:
public class DividerGridItemDecoration extends RecyclerView.ItemDecoration { private Drawable mDivider; private int mSize; private int mOrientation; public DividerGridItemDecoration(Resources resources, @ColorRes int color, @DimenRes int size, int orientation) { mDivider = new ColorDrawable(resources.getColor(color)); mSize = resources.getDimensionPixelSize(size); mOrientation = orientation; } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { int left; int right; int top; int bottom; if (mOrientation == LinearLayoutManager.HORIZONTAL) { top = parent.getPaddingTop(); bottom = parent.getHeight() - parent.getPaddingBottom(); final int childCount = parent.getChildCount(); for (int i = 0; i < childCount - 1; i++) { final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); left = child.getRight() + params.rightMargin; right = left + mSize; mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } else { left = parent.getPaddingLeft(); right = parent.getWidth() - parent.getPaddingRight(); final int childCount = parent.getChildCount(); for (int i = 0; i < childCount - 1; i++) { final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); top = child.getBottom() + params.bottomMargin; bottom = top + mSize; mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { if (mOrientation == LinearLayoutManager.HORIZONTAL) { outRect.set(0, 0, 0, mSize); } else { outRect.set(0, 0, mSize, 0); } } }
计算滑动距离
private int getScollYDistance() { LinearLayoutManager layoutManager = (LinearLayoutManager) showKeyFrameRv.getLayoutManager(); int position = layoutManager.findFirstVisibleItemPosition(); View firstVisiableChildView = layoutManager.findViewByPosition(position); int itemWidth = firstVisiableChildView.getWidth(); return (position) * itemWidth - firstVisiableChildView.getLeft(); }
参考博客:
http://blog.csdn.net/mr_wanggang/article/details/46707441
http://blog.csdn.net/lmj623565791/article/details/45059587
http://blog.csdn.net/skykingf/article/details/50827141
https://blog.piasy.com/2016/03/26/Insight-Android-RecyclerView-ItemDecoration/
http://blog.csdn.net/guolin_blog/article/details/10470797/
http://apkbus.com/blog-35555-59152.html
http://blog.csdn.net/xuehuayous/article/details/50394640
http://blog.csdn.net/huangxiaoguo1/article/details/53706971
相关文章推荐
- 支持上下拉刷新的RecycleView,基于androidPullToRefresh
- Android PullToRefresh 下拉刷新,上拉很多其它,支持ScrollView,ListView,可方便拓展GridView,WebView等
- Android PullToRefresh 下拉刷新,上拉更多,支持ScrollView,ListView,可方便拓展GridView,WebView等
- 利用android-Ultra-Pull-To-Refresh做的下拉刷新,支持viewpager等view完美嵌套
- 支持下拉刷新、上拉加载的RecyclerView,基于PullToRefresh
- PullToRefresh添加HeaderView(Banner轮播)
- pulltorefresh+recycleview 实现的瀑布流(带下拉刷新,上拉加载更多)
- Android RecyclerView上下拉刷新加载之PullToRefresh的结合使用
- 支持各种控件上/下拉刷新的android-pulltorefresh
- android-pulltorefresh 支持各种控件下拉刷新
- Android,PullToRefreshListView,addHeaderView错误!
- 使用 android-Ultra-Pull-To-Refresh 实现 WebView 下拉刷新
- PullToRefreshView中的listview添加addHeaderView
- PullToRefreshListView addHeaderView 下拉刷新冲突问题
- 下拉刷新与ViewPager冲突的处理,android-Ultra-Pull-To-Refresh下拉刷新嵌套ViewPager手势冲突
- Titanium tableview android 和 ios 下拉刷新(pull to refresh )
- Android:AutoScrollViewPager放在PullToRefresh中,解决不能下拉刷新问题
- React Native控件之PullToRefreshViewAndroid下拉刷新组件讲解(20)
- 为RecyclerView添加下拉刷新(PullToRefresh)功能
- pulltorefresh + StaggeredGridView 添加headerView后不能上拉加载更多的问题