当前位置: 首页 > news >正文

【Android】NestedScrollView的简单用法与滚动冲突、滑动冲突

一、NestedScrollView

1. 什么是 NestedScrollView

NestedScrollView 是 Android 中一个用于处理垂直方向滚动的布局组件,它继承自 FrameLayout,同时支持嵌套滑动(Nested Scrolling)机制。相比于传统的 ScrollViewNestedScrollView 专为解决嵌套滚动冲突问题设计,能够与其他支持嵌套滑动的子视图(如 RecyclerViewViewPager 等)协同工作。

2. 定义

NestedScrollView 是 Android Jetpack 中的组件,用于容纳能够垂直滚动的视图。当页面布局的内容超过屏幕高度时,可以通过滚动展示全部内容。同时,NestedScrollView 在滚动的过程中与子视图可以进行事件协作。

3. 与ScrollView的区别

NestedScrollViewScrollView 的主要区别在于它具备“嵌套滑动”(Nested Scrolling)功能。在 Android 中,嵌套滑动是一种滚动冲突处理机制,允许父视图和子视图协同工作,共同处理滑动事件。这种机制非常有用,特别是当你在一个滚动视图中嵌套另一个滚动视图时,它能够有效避免滑动冲突。

  • ScrollView:不支持嵌套滑动,通常会出现父子滑动视图的事件冲突,导致滑动体验不佳。
  • NestedScrollView:内置嵌套滑动机制,能够更好地处理父子视图的滚动事件,使页面更加流畅。

4. 常见使用场景

  • 表单页面:在一个页面中,可能会有许多输入框、按钮等,当这些内容超过屏幕时,使用 NestedScrollView 可以让整个页面可滚动。
  • 嵌套滚动视图:当你在一个滚动视图(如 RecyclerView)中嵌套了另一个滚动视图(如 ViewPagerHorizontalScrollView)时,NestedScrollView 能避免滑动事件冲突。
  • CoordinatorLayout 结合NestedScrollView 可以与 CoordinatorLayout 搭配使用,处理如 CollapsingToolbarLayoutAppBarLayout 等复杂的滚动联动效果。

5. 简单使用方法

下面是一个CoordinatorLayout中使用NestedScrollView并嵌套RecyclerView的简单用法:

<androidx.coordinatorlayout.widget.CoordinatorLayout android:layout_width="match_parent"android:layout_height="match_parent"xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"><androidx.core.widget.NestedScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"app:layout_behavior="@string/appbar_scrolling_view_behavior"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recyclerView"android:layout_width="match_parent"android:layout_height="wrap_content"android:nestedScrollingEnabled="false" /></LinearLayout></androidx.core.widget.NestedScrollView></androidx.coordinatorlayout.widget.CoordinatorLayout>
  • CoordinatorLayout 是整个布局的容器,用于协调多个滚动视图的交互,尽管当前只涉及了 NestedScrollView
  • NestedScrollView 管理页面的垂直滚动,并能够与其他支持嵌套滚动的视图配合使用。它容纳了 RecyclerView 并负责控制滚动。
  • RecyclerView 展示的是具体的滚动内容,使用 android:nestedScrollingEnabled="false"NestedScrollView 完全负责滚动处理,避免滚动冲突。

二、滚动冲突和滑动冲突

1. 区别

滚动冲突(Scroll Conflict)

​ 滚动冲突发生在嵌套滚动视图中。例如,一个 ScrollView 内部嵌套了一个 RecyclerView,或者一个 ViewPager 内嵌了一个 ScrollView。当用户在一个滚动视图上滑动时,系统需要决定哪个视图应该接收滚动事件,从而可能导致滚动冲突。

滑动冲突(Touch Conflict)

​ 滑动冲突通常发生在多个视图或组件尝试处理相同的触摸事件时。例如,一个 ViewPager 和一个 RecyclerView 都可以响应滑动手势,这会导致滑动冲突。滑动冲突通常涉及触摸事件的处理,而不是滚动事件的嵌套。

2. 处理方式

处理滚动冲突

滚动冲突通常发生在嵌套的滚动视图中,例如在一个 ScrollView 中嵌套了一个 RecyclerView。以下是几种常见的解决方法:

  1. 禁用子视图的嵌套滚动
  • 描述:禁用子视图的嵌套滚动功能,让父视图完全控制滚动行为。

  • 示例

    <androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recyclerView"android:layout_width="match_parent"android:layout_height="wrap_content"android:nestedScrollingEnabled="false" />
    
  1. 自定义 Behavior
  • 描述:创建自定义的 Behavior 类,控制滚动行为和滚动事件的传递。

  • 示例

    package com.example.nestedscrollviewtest;import android.content.Context;
    import android.util.AttributeSet;
    import android.view.View;import androidx.annotation.NonNull;
    import androidx.coordinatorlayout.widget.CoordinatorLayout;
    import androidx.core.view.ViewCompat;
    import androidx.core.widget.NestedScrollView;public class CustomBehavior extends CoordinatorLayout.Behavior<NestedScrollView> {public CustomBehavior() {super();}public CustomBehavior(Context context, AttributeSet attrs) {super(context, attrs);}@Overridepublic boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull NestedScrollView child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) {// 控制是否响应嵌套滑动return axes == ViewCompat.SCROLL_AXIS_VERTICAL;}@Overridepublic void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull NestedScrollView child, @NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) {// 处理嵌套滑动前的事件}
    }
    <androidx.coordinatorlayout.widget.CoordinatorLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"><androidx.core.widget.NestedScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"app:layout_behavior="com.example.nestedscrollviewtest.CustomBehavior"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recyclerView"android:layout_width="match_parent"android:layout_height="wrap_content"android:nestedScrollingEnabled="false" /></LinearLayout></androidx.core.widget.NestedScrollView></androidx.coordinatorlayout.widget.CoordinatorLayout>

处理滑动冲突

1. 外部拦截(onInterceptTouchEvent

  • 作用:用于拦截触摸事件,决定是否由当前视图处理该事件。
  • 如何工作:在父视图的 onInterceptTouchEvent 方法中,父视图会决定是否拦截事件并交给自己处理。如果返回 true,父视图将处理事件;如果返回 false,事件将传递给子视图处理。

NestedScrollView 中的外部拦截

NestedScrollView 作为一个容器视图,通常会处理其内部的滚动事件。为了确保它能够正确处理滚动事件,可以重写 NestedScrollViewonInterceptTouchEvent 方法来拦截触摸事件,并决定是否让其处理:

package com.example.nestedscrollviewtest;import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;import androidx.core.widget.NestedScrollView;public class CustomNestedScrollView extends NestedScrollView {public CustomNestedScrollView(Context context) {super(context);}public CustomNestedScrollView(Context context, AttributeSet attrs) {super(context, attrs);}public CustomNestedScrollView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {// 根据需要判断是否拦截事件// 例如,可以根据事件的类型或滚动方向来决定是否拦截return super.onInterceptTouchEvent(ev);}
}

2. 内部拦截(onTouchEvent

  • 作用:用于处理视图接收到的触摸事件。
  • 如何工作:在子视图的 onTouchEvent 方法中,子视图会处理传递给它的事件。如果子视图无法处理事件,它可以将事件传递给父视图或其他视图。

RecyclerViewonTouchEvent 方法负责处理其自己的触摸事件。通常,你不需要对 RecyclerViewonTouchEvent 进行特别处理,但要确保它正常工作。

public class CustomRecyclerView extends RecyclerView {public CustomRecyclerView(Context context) {super(context);}public CustomRecyclerView(Context context, AttributeSet attrs) {super(context, attrs);}public CustomRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}@Overridepublic boolean onTouchEvent(MotionEvent e) {// 默认情况下,RecyclerView 处理自己的触摸事件return super.onTouchEvent(e);}
}

3.拦截机制

滚动冲突和拦截机制

当你处理滚动冲突时(例如ScrollView 中嵌套 RecyclerView),内部拦截和外部拦截的目的都是在父视图和子视图之间决定谁来处理滚动事件。在这种情况下,使用拦截机制是为了解决多个滚动视图对事件的争夺

  • 内部拦截法:子视图决定是否处理事件。
    • 适用于子视图滚动逻辑复杂的情况,通常用于滚动冲突
  • 外部拦截法:父视图决定是否处理事件。
    • 适用于父视图需要优先处理事件的情况,常用于解决滚动冲突

滑动冲突和拦截机制

滑动冲突是由多个视图组件对触摸事件的竞争引发的,而不是滚动事件的嵌套。在滑动冲突的场景下,拦截机制也同样适用。比如在ViewPagerRecyclerView这类视图中,事件分发的冲突会涉及滑动方向和手势的识别。

  • 内部拦截法:子视图根据触摸事件的方向和类型,决定是否继续处理触摸事件或传递给父视图。
    • 适用于需要子视图有更多自定义处理的滑动场景。
  • 外部拦截法:父视图判断当前手势是否属于自己的处理范围,例如 ViewPager 判断是水平滑动,则拦截事件。
    • 常用于父视图需要根据手势类型做判断的滑动冲突场景。

以上就是本篇博客的所有内容


已经到底啦!!

相关文章:

【Android】NestedScrollView的简单用法与滚动冲突、滑动冲突

一、NestedScrollView 1. 什么是 NestedScrollView NestedScrollView 是 Android 中一个用于处理垂直方向滚动的布局组件&#xff0c;它继承自 FrameLayout&#xff0c;同时支持嵌套滑动&#xff08;Nested Scrolling&#xff09;机制。相比于传统的 ScrollView&#xff0c;N…...

【LeetCode】每日一题 2024_9_13 预算内的最多机器人数目(滑动窗口、单调队列)

LeetCode 启动&#xff01; 每日一题的题解重新开始连载&#xff01; 题目&#xff1a;预算内的最多机器人数目 题目链接&#xff1a;2398. 预算内的最多机器人数目 题目描述 代码与解题思路 func maximumRobots(chargeTimes []int, runningCosts []int, budget int64) (an…...

TypeScript中 any和unknown 的区别

1、给其他变量赋值 any可以给其他类型的变量重新赋值&#xff1b; 但unknown是不行的&#xff0c;unknown 可以保持类型安全&#xff0c;从而减少潜在的错误&#xff1b; 2、使用类型上的方法 any可以用类型上的方法&#xff0c;unknown是不可以的...

道可云人工智能元宇宙每日资讯|第五届深圳国际人工智能展(GAIE)在深圳会展中心举行

道可云元宇宙每日简报&#xff08;2024年9月12日&#xff09;讯&#xff0c;今日元宇宙新鲜事有&#xff1a; 成都&#xff1a;最高1000万元&#xff0c;研发川藏线数字文旅元宇宙空间 近日&#xff0c;成都市科学技术局启动2025年成都市第一批科技项目和第一批“常年申报”市…...

Bootstrap布局实例(偏移列)

偏移是一个用于更专业的布局的有用功能。它们可用来给列腾出更多的空间。例如&#xff0c;.col-xs-* 类不支持偏移&#xff0c;但是它们可以简单地通过使用一个空的单元格来实现该效果。 为了在大屏幕显示器上使用偏移&#xff0c;请使用 .col-md-offset-* 类。这些类会把一个…...

IP网络广播服务平台任意文件上传漏洞

文章目录 免责声明搜索语法漏洞描述漏洞复现修复建议 免责声明 本文章仅供学习与交流&#xff0c;请勿用于非法用途&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任 搜索语法 icon_hash"-568806419"漏洞描述 该系统在upload接口处可上传任…...

详细阐述Activity的生命周期

目录 1. onCreate()&#xff1a; 2. onStart()&#xff1a; 3. onResume()&#xff1a; 4. onPause()&#xff1a; 5. onStop()&#xff1a; 6. onRestart()&#xff1a; 7. onDestroy()&#xff1a; 活动生命周期图&#xff1a; 特别说明&#xff1a; 例子&#xff…...

spring boot+vue3学习之旅

前言 使用的是黑马程序员的教程&#xff0c;所有资料都来自于它的公众号&#xff0c;侵权即删&#xff0c;这里只做记录学习&#xff0c;然后我还遇到一个问题&#xff0c;不知道为啥idea每次打开一个新项目&#xff0c;maven路径就要重装&#xff0c;很麻烦。 新建项目 之…...

vue-watch监听功能(侦听器)详解使用

在Vue中&#xff0c;watch侦听器允许我们观察和响应Vue实例上数据的变化。当被侦听的数据发生变化时&#xff0c;可以执行异步操作或开销较大的操作&#xff0c;这是computed属性可能不适合的场景。watch侦听器提供了更灵活的方式来处理数据变化时的副作用。 基本用法 watch选…...

8.第二阶段x86游戏实战2-实现瞬移

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…...

uts+uniapp踩坑记录(vue3项目

杂记&#xff1a; web-view方面 内嵌html使用web-view时&#xff0c;直接用 uni.postMessage({data: {action: message // 你要传的信息}}); 示例上写的是用 document.addEventListener(UniAppJSBridgeReady, function() { uni.postMessage({ data: { action: postMe…...

《深度学习》OpenCV 高阶 图像金字塔 用法解析及案例实现

目录 一、图像金字塔 1、什么是图像金字塔 2、图像金字塔作用 1&#xff09;金字塔尺度间的图像信息补充 2&#xff09;目标检测与识别 3&#xff09;图像融合与拼接 4&#xff09;图像增强与去噪 5&#xff09;图像压缩与编码 二、用法解析 1、向下采样 1&#xff09;概念…...

dirty pages , swapiness 查看SWAP占用进程

文章说了这么多的意思 就是不要过度分配不用的内存。虽然脏块不会写入swap&#xff0c;但是占了物理内存&#xff0c;浪费空间&#xff0c;可能导致进行了很多不必要的交换&#xff08;虽然判断很少要进swap&#xff0c;判断要不要也要时间。。。&#xff09;。 To verify whic…...

Spring Boot项目更改项目名称

背景&#xff1a;新项目开始前&#xff0c;往往需要初始化功能&#xff0c;拿到基础版本后更改项目对应的名称等信息。 更改步骤如下&#xff1a; 1、修改目录名称。 打开本地项目&#xff0c;右键修改项目名称。 2、修改maven项目的pom依赖 修改parent及modules项目名称&…...

Hive SQL基础语法及查询实践

目录 基础语法 1. 官网地址 2. 查询语句语法 基本查询&#xff08;Select…From&#xff09; 数据准备 &#xff08;0&#xff09;原始数据 &#xff08;1&#xff09;创建部门表 &#xff08;2&#xff09;创建员工表 &#xff08;3&#xff09;导入数据 全表和特定列查…...

k8s service如何实现流量转发

1 基本概念 Service&#xff1a;在Kubernetes&#xff08;K8s&#xff09;中&#xff0c;Service用于将流量转发到后端的Pod中。Service提供了一种稳定的网络入口&#xff0c;尽管后端的Pod可能会动态改变 kube-proxy: kube-proxy是Kubernetes集群中的核心组件之一&#xff0…...

每日一练:K个一组翻转链表

25. K 个一组翻转链表 - 力扣&#xff08;LeetCode&#xff09; 一、题目要求 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。 k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍&#x…...

昨晚,OpenAI震撼发布o1大模型!我们正式迈入了下一个时代。

大半夜的&#xff0c;OpenAI抽象了整整快半年的新模型。 在没有任何预告下&#xff0c;正式登场。 正式版名称不叫草莓&#xff0c;草莓只是内部的一个代号。他们的正式名字&#xff0c;叫&#xff1a; 为什么取名叫o1&#xff0c;OpenAI是这么说的&#xff1a; For complex …...

MySql8.x---开窗函数

1、定义 语法结构&#xff1a; ** 开窗函数|聚合函数 over([分组函数] [排序函数] [自定义窗口]) ** 分组函数&#xff1a;partition by ...&#xff0c;根据指定的字段对表分组&#xff0c;分组字段可以有多个。省略时表示整个表为一组。 排序函数&#xff1a;order by ...&…...

图文讲解HarmonyOS应用发布流程

HarmonyOS应用的开发和发布过程可以分为以下几个步骤&#xff1a;证书生成、应用开发、应用签名和发布。 1. 证书生成&#xff1a; 在开始开发HarmonyOS应用之前&#xff0c;首先需要生成一个开发者证书。开发者证书用于标识应用的开发者身份并确保应用的安全性。可以通过Har…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...