Android滑动冲突之完美实现RecycleView+下拉刷新+上拉加载+粘性Header

本文探讨如何在Android应用中集成RecycleView、下拉刷新、上拉加载和粘性头部,并避免滑动冲突。通过使用Google的SwipeRefreshLayout和RecyclerView,结合自定义StickyNavLayout处理滑动事件,实现了导航栏、广告栏、Indicator和可滚动内容的交互。在滑动过程中,Banner条会随着手势上移,下拉刷新功能在特定条件下激活。

前言:在日常的开发中,我们可能遇到各种各样的需求,今天我们主要来一起探究RecycleView+下拉刷新+上拉加载+粘性头部,同时避免滑动冲突的联合实现过程。看到这里,你可能心中暗想,没图说个JB!!!客官别急,下面我们就来看一下最终实现的效果:
这里写图片描述

上面就是我们最终要实现的效果,现在我们先来对它进行拆分和分析,如下图所示:
这里写图片描述

从上图可以看出,这是最原始的状态。大致可分为导航栏、广告栏、Indicator、Recycleview和下拉刷新。当向上滑动的时候,先由外部ViewGroup拦截滑动事件,同时Banner条向上移动。当Banner条完全隐藏的时候,Indicator固定在头部,同时由RecycleView接管滑动事件,此时向下拉动的时候,下拉刷新是失效的,只有当Banner完全现实的时候,下下滑动才会出现下拉刷新效果,(这里不得不说,如果把下拉刷新加到Indicator下方,实现要简便得多)。以上大致就是我们需要实现效果的完整流程,下面我们将从代码的角度为您一一剖析。

流程分析:

使用组件:

  1. 下拉刷新:使用Google自带SwipeRefreshLayout。
  2. 列表:使用Google自带RecyclerView。
  3. 自定义StickyNavLayout实现滑动事件的分发和处理。
  4. 广告栏:第三方Banner。
  5. Indicator:使用横向的RecyclerView。

自定义StickyNavLayout实现原理:

public class StickyNavLayout extends LinearLayout {
   
   
    private static final String TAG = "StickyNavLayout";
    //Banner条
    private View mTop;
    //导航的Indicator
    private View mNav;
    //Banner条的高度
    private int mTopViewHeight;
    //    private ViewGroup mInnerScrollView;
    //判断Banner条是否隐藏的标志位
    private boolean isTopHidden = false;
    private OverScroller mScroller;
    //显示内容的列表组件
    private RecyclerView mRecycleView;
    //和滑动相关的参数
    private VelocityTracker mVelocityTracker;
    private int mTouchSlop;
    private int mMaximumVelocity, mMinimumVelocity;
    private float mLastY;
    private boolean mDragging;
    //Indicator是否置顶的标志位
    private boolean isStickNav;
    private boolean isInControl = false;
    private int stickOffset;
    //内容组件的宽度和高度
    private int mViewPagerMaxHeight;
    private int mTopViewMaxHeight;
    private boolean isScroll = true;

    public StickyNavLayout(Context context) {
        this(context, null);
    }

    public StickyNavLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public StickyNavLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setOrientation(LinearLayout.VERTICAL);
        //取出xml文件中设置的参数
        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.StickNavLayout);
        isStickNav = a.getBoolean(R.styleable.StickNavLayout_isStickNav, false);
        stickOffset = a.getDimensionPixelSize(R.styleable.StickNavLayout_stickOffset, 0);
        a.recycle();
        //初始化滑动相关的数据
        mScroller = new OverScroller(context);
        mVelocityTracker = VelocityTracker.obtain();
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        mMaximumVelocity = ViewConfiguration.get(context)
                .getScaledMaximumFlingVelocity();
        mMinimumVelocity = ViewConfiguration.get(context)
                .getScaledMinimumFlingVelocity();
    }

    public void setIsStickNav(boolean</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值