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

2024-09-07 02:20

本文主要是介绍【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" />
    
  • 适用场景:当 RecyclerView 或其他滚动视图嵌套在 ScrollViewNestedScrollView 中时。

  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);}
}

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


已经到底啦!!

这篇关于【Android】NestedScrollView的简单用法与滚动冲突、滑动冲突的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1143785

相关文章

C#中async await异步关键字用法和异步的底层原理全解析

《C#中asyncawait异步关键字用法和异步的底层原理全解析》:本文主要介绍C#中asyncawait异步关键字用法和异步的底层原理全解析,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录C#异步编程一、异步编程基础二、异步方法的工作原理三、代码示例四、编译后的底层实现五、总结C#异步编程

如何解决idea的Module:‘:app‘platform‘android-32‘not found.问题

《如何解决idea的Module:‘:app‘platform‘android-32‘notfound.问题》:本文主要介绍如何解决idea的Module:‘:app‘platform‘andr... 目录idea的Module:‘:app‘pwww.chinasem.cnlatform‘android-32

python3 gunicorn配置文件的用法解读

《python3gunicorn配置文件的用法解读》:本文主要介绍python3gunicorn配置文件的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录python3 gunicorn配置文件配置文件服务启动、重启、关闭启动重启关闭总结python3 gun

MySQL 中的 LIMIT 语句及基本用法

《MySQL中的LIMIT语句及基本用法》LIMIT语句用于限制查询返回的行数,常用于分页查询或取部分数据,提高查询效率,:本文主要介绍MySQL中的LIMIT语句,需要的朋友可以参考下... 目录mysql 中的 LIMIT 语句1. LIMIT 语法2. LIMIT 基本用法(1) 获取前 N 行数据(

C#中DrawCurve的用法小结

《C#中DrawCurve的用法小结》本文主要介绍了C#中DrawCurve的用法小结,通常用于绘制一条平滑的曲线通过一系列给定的点,具有一定的参考价值,感兴趣的可以了解一下... 目录1. 如何使用 DrawCurve 方法(不带弯曲程度)2. 如何使用 DrawCurve 方法(带弯曲程度)3.使用Dr

Android实现打开本地pdf文件的两种方式

《Android实现打开本地pdf文件的两种方式》在现代应用中,PDF格式因其跨平台、稳定性好、展示内容一致等特点,在Android平台上,如何高效地打开本地PDF文件,不仅关系到用户体验,也直接影响... 目录一、项目概述二、相关知识2.1 PDF文件基本概述2.2 android 文件访问与存储权限2.

Android Studio 配置国内镜像源的实现步骤

《AndroidStudio配置国内镜像源的实现步骤》本文主要介绍了AndroidStudio配置国内镜像源的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、修改 hosts,解决 SDK 下载失败的问题二、修改 gradle 地址,解决 gradle

C++ vector的常见用法超详细讲解

《C++vector的常见用法超详细讲解》:本文主要介绍C++vector的常见用法,包括C++中vector容器的定义、初始化方法、访问元素、常用函数及其时间复杂度,通过代码介绍的非常详细,... 目录1、vector的定义2、vector常用初始化方法1、使编程用花括号直接赋值2、使用圆括号赋值3、ve

MySQL中FIND_IN_SET函数与INSTR函数用法解析

《MySQL中FIND_IN_SET函数与INSTR函数用法解析》:本文主要介绍MySQL中FIND_IN_SET函数与INSTR函数用法解析,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一... 目录一、功能定义与语法1、FIND_IN_SET函数2、INSTR函数二、本质区别对比三、实际场景案例分

pytorch之torch.flatten()和torch.nn.Flatten()的用法

《pytorch之torch.flatten()和torch.nn.Flatten()的用法》:本文主要介绍pytorch之torch.flatten()和torch.nn.Flatten()的用... 目录torch.flatten()和torch.nn.Flatten()的用法下面举例说明总结torch