当前位置: 首页 > 编程笔记 >

Android ScrollView粘性头部代码分享

徐文斌
2023-03-14
本文向大家介绍Android ScrollView粘性头部代码分享,包括了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地址。

以上就是本次小编整理的全部内容,感谢你对小牛知识库的支持。

 类似资料:
  • 我正在编写一个 Java EE 应用程序,使用 Jetty 作为应用程序服务器,以便在开发过程中使用。虽然(重新)部署速度很快,但我希望Java代码更改能够立即反映在正在运行的服务器中,而无需重新启动。(我已经在使用设置来查看对静态服务内容的即时更改)。 我看到过关于使用Maven Jetty插件和设置scanInterval来重新部署web上下文的问题,但这不是我想做的。我的Jetty服务器是从

  • 查看用户在某个时间单位内,进行某个事件的频次分布,以此分析用户对功能的使用情况或依赖程度。 1.1. 1. 功能说明 查看满足特定条件的用户在某个时间单位内,进行某个事件的频次分布; 分析产品或功能对用户来说的粘性程度; 页面如下图: Figure: images 1.2. 2.操作详解 1.2.1. a.选择时间单位、事件和筛选条件 Figure: images 标识 说明 A 统计中使用的时间

  • 问题内容: 我正在尝试创建一个粘性补充标题,该标题始终保持在顶部,并且不会响应滚动事件。到目前为止,我发现的解决方案仍然可以对快速滚动进行反应,并使用自定义flowLayout进行了修复,这也可能是解决我的问题的方法。 我想要这种方式的原因是该标头在其他地方使用并且应该可重用。我希望可以通过这种方式解决此问题,而不必创建单独的视图。 当我在Swift中进行此操作时,在Swift中有一个示例将是很棒

  • 一、什么是用户粘性分析? 诸葛io的用户粘性分析,可以让你了解你的产品或某个功能粘住用户的能力如何。 二、有哪些应用场景? 使用用户粘性分析功能,你可以了解到一周内或一个月内用户到底有多少天在使用你的产品甚至是某个功能。 对于大多数产品而言,用户「一周内使用了5次」并不能反映用户对产品的依赖程度,因为这5次可能发生在一个较短的连续时间内,比如用户一天内连续尝试了5次之后,没有兴趣,剩余的几天里,都

  • 我想知道粘性和非粘性会议之间的区别。我从网上读到的: 粘滞:只有一个会话对象将在那里。 非粘性会话:每个服务器节点的会话对象

  • 本文向大家介绍PHP批量去除BOM头代码分享,包括了PHP批量去除BOM头代码分享的使用技巧和注意事项,需要的朋友参考一下

  • 本文向大家介绍C# Partial:分部方法和分部类代码实例,包括了C# Partial:分部方法和分部类代码实例的使用技巧和注意事项,需要的朋友参考一下 这段代码只会输出:Hello,并且不会造成编译错误。

  • 我有一个wordpress插件,可以上传用户头像。我正在尝试使用一段显示缩略图的代码,并将其放在一个短代码中,这样我就可以将缩略图放在网站的任何位置。 我对php比较陌生,我知道如何为wordpress启动一个短代码,但我不知道如何构造短代码来承载php。有谁能给我提个建议吗? php下面的代码是插件文件的原文: 我想放在短代码中的代码如下,基本上它显示了缩略图。我试图用这个在functions.