Android ScrollView粘性头部代码分享

前言,一天在点外卖的时候,注意到饿了么列表页的滑动效果不错,但是觉得其中的手势滑动还是挺复杂的,正好又碰到了在熟悉Touch事件的理解当中,所以就抽空对着饿了么的列表页面尝试写写这个效果

1.先贴一个实现的效果图

逻辑是当外部的ScrollView没有滑到底部的时候,往上滑动的时候,是滑动外部的ScrollView,当外部的ScrollView到达底部的时候,我们再网上滑,就是滑动内部的列表了,另外在左右滑动的时候,当左右滑动的距离大于minPageSlop的话,那么就执行左右滑动。

如下是仿饿了么的列表页的效果图:

2.引入

在项目根目录的build.gradle文件下增加jitpack的repo地址
allprojects {
 repositories {
  jcenter()
  maven { url "https://jitpack.io" }
 }
}
在需要引入的module中引入library
dependencies { implementation 'com.github.WelliJohn:StickScrollView:0.0.3'
}

3.界面的布局说明

<wellijohn.org.stickscrollview.ScrollViewWithStickHeader
    android:id="@+id/stick_scroll_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1">
    <LinearLayout
      android:id="@+id/ll"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
      android:focusableInTouchMode="true"
      android:orientation="vertical">
      //这里是header部分,可以随便自定义
      </LinearLayout>
      <LinearLayout
        android:id="@+id/ll_stick_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
 <android.support.design.widget.TabLayout
  android:id="@+id/order_manager_tabs"
    android:layout_width="match_parent"
          android:layout_height="50dp"
          android:background="#FFFFFF"
          tools:tabGravity="fill"
          tools:tabMode="fixed" />
        <android.support.v4.view.ViewPager
          android:id="@+id/vp"
    android:layout_width="match_parent"
android:layout_height="wrap_content" />
      </LinearLayout>
    </LinearLayout>
</wellijohn.org.stickscrollview.ScrollViewWithStickHeader>

比如我们看到的仿饿了么的列表页界面,我们就需要在ViewPager设置Fragment,fragment中是左右两个列表,看下fragment的xml设置:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/ll"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="horizontal">
  <wellijohn.org.stickscrollview.ChildRecyclerView
    android:id="@+id/child_recyclerview"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:background="#EEEEEE" />
  <wellijohn.org.stickscrollview.ChildRecyclerView
    android:id="@+id/child_recyclerview_right"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:background="#FFFFFF"
    android:layout_weight="3" />
</LinearLayout>

4.注意事项

ScrollViewWithStickHeader内部目前支持放置ViewPager,ScrollView,RecyclerView,WebView ScrollView,RecyclerView,WebView需要对应使用ChildScrollView,ChildRecyclerView,ChildWebView 我们在使用的时候,需要调用mStickScrollView.setContentView(mContentView);mLLStickList就是我们需要StickHeader+列表的部分,如果你没有StickHeader的话,那么直接设置列表进来也可以,总之,你想滑动到哪个位置接下来滑动就是单纯下面的部分滑动,那你就把下面的View整体设置为mContentView。刚刚那个的ContentView是id为ll_stick_list的View。另外在这里ScrollViewWithStickHeader增加autoscroll属性,默认是关闭的,如果autoscroll:true的话,在我们手指放开的时候,contentView会判断是否自动滑动到顶部还是隐藏不见。

5.0.0.3版本修复当有底部有操作栏的时候,界面的滚动出现错乱的问题。

当我们底部有view需要固定的时候,我们需要通过mStickScrollView.setBottomView(mViewBottom);就可以了,如下所示:

6.任何控件的使用我们最好都知道它的实现方式,所以在这里简单介绍下这款控件的设计思路(ChildScrollView,ChildRecyclerView,ChildWebView下面的都称为子ScrollView)? 6.1.我们什么时候应该让外部的ScrollView执行滑动事件,什么时候让子ScrollView执行滑动。在Android中我们有一个方法getParent().requestDisallowInterceptTouchEvent(true);就是让view获取到对应的事件。 6.2.既然我们知道了怎么让view的touch事件,接下来我们就要明白在什么情况下我们应该让父view执行滚动事件,什么时候让子view执行滚动事件。如下,我列了表格:

父ScrollVIew

子ScrollView

手势滑动方向

滑动事件交由哪个view控制 不在底部顶部向上父ScrollView 不在底部顶部向下父ScrollView 底部不在顶部向上子ScrollView 底部不在顶部向下子ScrollView 底部顶部向下父ScrollView 底部顶部向上子ScrollView

在这里当父ScrollView不在底部的时候,不会出现子ScrollView不在顶部的情况,所以在这里就不分析了。

6.3.分析了,在什么情况我们应该让子ScrollVIew还是父ScrollView捕获滑动事件了,我们就可以在我们的子ScrollView中编写对应的代码处理了?

如下面是一段ChildScrollView的onTouchEvent方法的重写,其他的ChildRecyclerView和ChildWebView处理也是一样的:

@Override
public boolean onTouchEvent(MotionEvent event) {
  if (mScrollViewWithStickHeader == null) return super.onTouchEvent(event);
  int action = event.getAction();
  if (action == MotionEvent.ACTION_DOWN) {
    mLastX = event.getX();
    mLastY = event.getY();
    //首先判断外层ScrollView是否滑动到底部
    if (mScrollViewWithStickHeader.isBottom()) {
      getParent().requestDisallowInterceptTouchEvent(true);
      return super.onTouchEvent(event);
    } else {
      //拦截事件 本身不处理
      getParent().requestDisallowInterceptTouchEvent(false);
      return false;
    }
  }
  if (action == MotionEvent.ACTION_MOVE) {
    float nowY = event.getY();
    if (!mScrollViewWithStickHeader.isBottom() && !isScrolledToTop && nowY - mLastY > 0) {
      if (Math.abs(event.getX() - mLastX) < minPageSlop) {
        getParent().requestDisallowInterceptTouchEvent(true);
        return super.onTouchEvent(event);
      } else {
        getParent().requestDisallowInterceptTouchEvent(true);
        return false;
      }
    } else if (mScrollViewWithStickHeader.isBottom() && !isScrolledToBottom && nowY - mLastY < 0) {
      if (Math.abs(event.getX() - mLastX) < minPageSlop) {
        getParent().requestDisallowInterceptTouchEvent(true);
        return super.onTouchEvent(event);
      } else {
        getParent().requestDisallowInterceptTouchEvent(true);
        return false;
      }
    } else if (mScrollViewWithStickHeader.isBottom() && !isScrolledToTop && nowY - mLastY > 0) {
      if (Math.abs(event.getX() - mLastX) < minPageSlop) {
        getParent().requestDisallowInterceptTouchEvent(true);
        return super.onTouchEvent(event);
      } else {
        getParent().requestDisallowInterceptTouchEvent(true);
        return false;
      }
    } else {
      getParent().requestDisallowInterceptTouchEvent(false);
    }
  }
  if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
    getParent().requestDisallowInterceptTouchEvent(false);
  }
  return super.onTouchEvent(event);
}

这样的话,我们就能实现固定头部的ScrollView了。

7.github地址

以上就是本次小编整理的全部内容,感谢你对我们的支持。

您可能感兴趣的文章:

  • android开发仿ios的UIScrollView实例代码
  • 详解Android ScrollView嵌套EditText出现的滑动问题
  • android ScrollView实现下拉放大头部图片
  • Android自定义scrollView实现顶部图片下拉放大
  • Android给scrollView截图超过屏幕大小形成长图
  • Android沉浸式状态栏 + actionBar渐变 + scrollView顶部伸缩效果
  • Android开发基于ScrollView实现的渐变导航栏效果示例
  • Android自定义ScrollView使用自定义监听
  • Android开发实现ScrollView中嵌套两个ListView的方法
  • Android开发实现标题随scrollview滑动变色的方法详解
  • Android Webview与ScrollView的滚动兼容及留白处理的方法
  • Android 自定义 HorizontalScrollView 打造多图片OOM 的横向滑动效果(实例代码)
(0)

相关推荐

  • Android Webview与ScrollView的滚动兼容及留白处理的方法

    本文介绍了Webview与ScrollView的滚动兼容及留白处理,分享给大家,具体如下: 背景 开发中我们经常会遇到使用网页来显示图文内容,而且往往我们会遇到webview嵌套在scrollview的这种情况,这就开始让人蛋疼了!"为嘛,我的webview加载出来的网页只显示很小一点,其他都不显示了?" "当我重新刷新页面后,为什么webview会出现留白的情况?" ----------------- 天啊,难道就不能好好的吗?! 为了解决项目中这些蛋疼的问题,试

  • Android自定义scrollView实现顶部图片下拉放大

    本文实例为大家分享了scrollView实现顶部图片下拉放大的具体代码,供大家参考,具体内容如下 之前的scrollView顶部图片下拉放大在之后的项目用到了几次,但没次都写在Activity中很麻烦,也不方便复用.这几天有空,所以重新使用自定义scrollView的方法实现这个效果.原理和之前的基本是一致的,所以也不多说了,直接上代码. package com.example.myapplication.dropzoom; import android.animation.ObjectAnim

  • android开发仿ios的UIScrollView实例代码

    今天重新装了编译器,结果崩无极限,真是日了狗了了.刚刚才知道问题在哪边. 好了,说正事,对于ios开发我没接触,不是很了解,百度了半天,差不多就是UIScrollView的把.如果不对,请指证.具体什么效果呢,我刚才拿朋友的iphone手机看了下,iphone的设置界面,第一个列表往下拉可以继续滚,上拉同理.不过android好像没有自带的这种情况. 我把这种效果称为滚无极限的scollview. 下面就来上源码: 首先,最最最重要的就是判断当前视图是否为空,你空视图滚不滚好像没啥区别,除了an

  • Android开发实现ScrollView中嵌套两个ListView的方法

    本文实例讲述了Android开发实现ScrollView中嵌套两个ListView的方法.分享给大家供大家参考,具体如下: 做的项目中要使用两个ListView在同一个页面上下显示,因为数据源不同,不能通过在Adapter中设置标志位去区分显示,最后只能硬着头皮做一个ScrollView嵌套两个ListView,但按正常情况是不能同时显示的,会出现上面的ListView完全显示,下面的只显示一个Item,查了一些资料终于成功了 主要有一个ListViewUtility ,代码如下: import

  • Android 自定义 HorizontalScrollView 打造多图片OOM 的横向滑动效果(实例代码)

    自从Gallery被谷歌废弃以后,Google推荐使用ViewPager和HorizontalScrollView来实现Gallery的效果.的确HorizontalScrollView可以实现Gallery的效果,但是HorizontalScrollView存在一个很大的问题,如果你仅是用来展示少量的图片,应该是没问题的,但是如果我希望HorizontalScrollView可以想ViewPager一样,既可以绑定数据集(动态改变图片),还能做到,不管多少图片都不会OOM(ViewPager内

  • android ScrollView实现下拉放大头部图片

    前言 之前做项目的时候,需要实现类似微博个人主页的ScrollView效果,就是到顶部时继续下拉会放大顶部的图片.然后在网上找了一篇相关的实现,效果非常好,代码也很简洁易懂.(传送门: 自定义scrollView实现顶部图片下拉放大),那么我这里就只是在其基础上修改了一点点而已,比如在代码中控制图片居中.增加动态设置放大的控件.使用自定义的最大放大倍数等,都是很简单的修改,还添加了滑动的监听回调(项目需要). 效果如下: 思路 老样子,我们先来说下思路,比起代码,思路才是最重要的.具体步骤如下:

  • Android自定义ScrollView使用自定义监听

    本文实例为大家分享了Android使用自定义监听的具体代码,供大家参考,具体内容如下 实现效果:自定义一个ScrollView使用自定义监听,当手指在scrollView滑动滑动的时候做一些事情,我这边简单操作就直接弹出静态吐司显示xy轴的坐标(Toast使用的是静态Toast,源码里面有) 这是在自定义的scrollView设置自定义监听 @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()

  • Android给scrollView截图超过屏幕大小形成长图

    很多的时候,我们想要分享一个界面的所有内容,可是内容太多,超过了屏幕的大小,简单的截屏已经满足不了我们的需要,这时候我们就可以根据布局里scrollView的高度来截取图片. 代码如下: /** * 截取scrollview的屏幕 * @param scrollView * @return */ public static Bitmap getBitmapByView(ScrollView scrollView) { int h = 0; Bitmap bitmap = null; // 获取s

  • Android开发基于ScrollView实现的渐变导航栏效果示例

    本文实例讲述了Android开发基于ScrollView实现的渐变导航栏效果.分享给大家供大家参考,具体如下: 前些日子项目要在原来的页面上加入渐变导航栏的功能,查了很多资料,很多资源都是监听到listview的高度来实现渐变导航栏的效果,可是项目里面很多的界面都是使用ScrollView来实现滑动效果. 实在没办法,就自己写了一个test来实现这个效果. 话不多说,马上看一下思路吧,其实渐变导航栏无非就是改变导航栏的透明度也就是可以设定一个高度,根据这个高度,监听ScrollView滑动的距离

  • 详解Android ScrollView嵌套EditText出现的滑动问题

    今天项目中需求是写出一个很简单的edittext输入框,但要求当输入字数过长时需要上下滑动以便查看所有文字,因为页面底部有一个"确定"的button,但刚开始输入框内的问题怎么都滑动不了,我一开始就想到了这是事件传递冲突问题,但试了很多种方法都不行,最后也是一个一个试才解决的,不多说,贴代码: <ScrollView android:id="@+id/sc_view" android:layout_width="match_parent"

  • Android沉浸式状态栏 + actionBar渐变 + scrollView顶部伸缩效果

    闲话不多说,直接上图. 给大家讲讲我的编程思想吧. 第一部分:沉浸式状态栏(API-Level 19, Android4.4 KitKat 之后加入的东西),而且在Api-Level 21版本中新增了一个属性(下面会说到).所以,style文件应该声明三份. values <style name="TranslucentTheme" parent="@style/AppTheme"> </style> values-19 <style

  • Android开发实现标题随scrollview滑动变色的方法详解

    本文实例讲述了Android开发实现标题随scrollview滑动变色的方法.分享给大家供大家参考,具体如下: 要实现某个view的背景透明度跟随scrollview滑动而改变需要重新scrollview的onOverScrolled方法,该方法随着滑动变化(包括手指滑动.手指移开惯性滑动)而响应,所以最适合做变色处理. step1:设定布局 由于我们要实现的是滑动时标题的背景透明度改变,固定顶部的标题view不能在srcollview里面跟随滑动,所以需要这样布局: <FrameLayout

随机推荐