支持上下拉刷新的RecycleView,基于androidPullToRefresh,添加RecycleView HeaderView

如题,基于android PullToRefresh的支持上拉刷新下拉加载的RecycleView
直接上码:

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().setLastUpdatedLabel(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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值