鸿蒙开发:使用nestedScroll解决滑动冲突

简介: nestedScroll属性的作用,主要是,用于设置嵌套滚动选项,设置前后两个方向的嵌套滚动模式,实现与父组件的滚动联动。

前言


本文基于Api13


在实际的开发中,滑动冲突在所难免,常见于可滚动的容器组件嵌套使用,比如Scroll组件嵌套List组件,List组件嵌套了Grid组件等等,只要是滚动容器组件嵌套,令人厌烦的滑动冲突就会扑面而来,十分让人抓狂;如何处理滑动冲突,成了开发中的必修之课,然而,鸿蒙当中的处理方式,相对与Android端而言,似乎更加的直观和简单,使用一个属性便可以搞定,那就是nestedScroll。

简单案例


案例很是简单,外层是一个Scroll滚动容器,内部也有一个List组件滚动组件,在List上面有一个普通的组件。


@Entry
@Component
struct Index {
  build() {
    Scroll() {
      Column() {
        Text("我是顶部的组件")
          .width("100%")
          .height(200)
          .textAlign(TextAlign.Center)
          .backgroundColor(Color.Pink)
          .fontColor(Color.White)
        List() {
          ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], (item: number) => {
            ListItem() {
              Text(item.toString())
                .width("100%")
                .height(80)
                .textAlign(TextAlign.Center)
            }
          })
        }
        .width("100%")
        .height("100%")
        .scrollBar(BarState.Off)
        .divider({ color: Color.Gray, strokeWidth: 1 })
        .edgeEffect(EdgeEffect.None)
      }
    }.width("100%")
    .height("100%")
    .scrollBar(BarState.Off)
  }
}


效果如下所示:



我们想要的效果是,先让顶部的组件滚动上去,然后再滚动下面的List组件,我们运行看下效果:



显然未达到我们的效果,这就是滑动冲突导致的,这种情况下,做为子组件的List组件,一定是先把滑动事件交给Scroll组件,等Scroll组件滚动到边缘后,再把滑动事件交给自己,这样的流程也是正确的,如何做到呢,前边已经说过了,那就是nestedScroll属性。

每个滚动容器组件都有一个nestedScroll属性,主要解决嵌套滚动模式下的的滑动冲突,我们给List组件设置一下,代码如下:


.nestedScroll({
          scrollForward: NestedScrollMode.PARENT_FIRST,
          scrollBackward: NestedScrollMode.SELF_FIRST
        })


设置完后,再看下效果:



可以看到,已经完美的解决了滑动冲突,达到了我们想要的效果。


了解nestedScroll


通过前言中的案例,我们基本上已经知道了nestedScroll属性的作用,主要是,用于设置嵌套滚动选项,设置前后两个方向的嵌套滚动模式,实现与父组件的滚动联动。



我们重点关注一下NestedScrollOptions这个参数,其中有两个值,分别是scrollForward和scrollBackward,一个代表往末尾端滚动,一个代表往起始端滚动。



两个参数都有一个共同的值类型NestedScrollMode,可供选择的有以下几个值:


名称

说明

SELF_ONLY

只自身滚动,不与父组件联动。

SELF_FIRST

自身先滚动,自身滚动到边缘以后父组件滚动。父组件滚动到边缘以后,如果父组件有边缘效果,则父组件触发边缘效果,否则子组件触发边缘效果。

PARENT_FIRST

父组件先滚动,父组件滚动到边缘以后自身滚动。自身滚动到边缘后,如果有边缘效果,会触发自身的边缘效果,否则触发父组件的边缘效果。

PARALLEL

自身和父组件同时滚动,自身和父组件都到达边缘以后,如果自身有边缘效果,则自身触发边缘效果,否则父组件触发边缘效果。


举例使用

前言中,我们简单使用Scroll组件嵌套List组件举了一个例子,我们再来看一个Scroll组件嵌套Web组件的案例。


import webview from '@ohos.web.webview'
@Entry
@Component
struct Index {
  private controller: webview.WebviewController = new webview.WebviewController()
  build() {
    Scroll() {
      Column() {
        Text("我是顶部的组件")
          .width("100%")
          .height(200)
          .textAlign(TextAlign.Center)
          .backgroundColor(Color.Pink)
          .fontColor(Color.White)
        Web({
          src: "https://juejin.cn/user/1398234520239095/columns",
          controller: this.controller
        })
          .nestedScroll({
            scrollForward: NestedScrollMode.PARENT_FIRST,
            scrollBackward: NestedScrollMode.SELF_FIRST
          })
      }
    }.width("100%")
    .height("100%")
    .scrollBar(BarState.Off)
  }
}


以上的效果和前言中基本一致,不在贴效果了,其实再多的案例,基本上都是一样的,只是nestedScroll中的值不一样而已。


相关总结


在实际的开发中,远远要比前边的案例复杂,比如我之前封装的刷新库,滚动组件上面有刷新头,下面也有加载尾,还有更复杂的,列表吸顶操作等等,一个nestedScroll属性是远远不够的,往往还要和滑动监听,是否滚动到了顶部和尾部等相结合,才能实现我们实际的效果。


比如,还是以上的案例,我们在List组件下面再增加一个底部的组件,我们运行看下效果:


显然之前配置的nestedScroll属性只满足了顶部的组件,而底部的组件在滑动的过程中明显有滑动冲突,并没有达到我们的预期,其实对于底部,上滑是先滚动自己后滚动父组件,下滑是要先滚动父组件,然后再去滚动自身组件的。



针对以上的问题,其实处理有多种方式,最简单的莫过于,底部组件在最后一个组件下面,当做List组件的部分,当然了顶部组件也可以这么去做,这样就不存在滑动冲突。


if (index == this.dataArray.length - 1) {
                Column() {
                  Text(item.toString())
                    .width("100%")
                    .height(80)
                    .textAlign(TextAlign.Center)
                  
                  Text("我是底部的组件")
                    .width("100%")
                    .height(200)
                    .textAlign(TextAlign.Center)
                    .backgroundColor(Color.Pink)
                    .fontColor(Color.White)
                }
  }


我们看下效果:



把组件加到首尾数据的位置,这种方式会存在一个问题,比如说,如果没有数据呢?顶部组件和底部组件那么就无法显示,再比如如果加载的不是List组件,而是一个Grid组件或者其他的滚动组件呢?显然处理上有很大的问题。


这个作业留给友友们,你们知道如何解决吗?


相关文章
|
11天前
|
人机交互 UED 索引
41.[HarmonyOS NEXT Row案例九] 打造流畅可滑动列表项:滑动操作按钮的高级实现
在现代移动应用中,可滑动列表项是一种常见且高效的交互方式,它允许用户通过水平滑动列表项来显示隐藏的操作按钮,如删除、置顶、归档等。本教程将详细讲解如何使用HarmonyOS NEXT的Row组件结合手势和动画创建一个流畅的可滑动列表项,实现滑动操作按钮的高级交互效果。
48 8
|
11天前
|
UED 容器
5.HarmonyOS Next开发宝典:掌握Flex布局的艺术
Flex布局(弹性布局)是HarmonyOS Next中最强大的布局方式之一,它提供了一种更加高效、灵活的方式来对容器中的子元素进行排列、对齐和分配空间。无论是简单的居中显示,还是复杂的自适应界面,Flex布局都能轻松应对。
34 0
|
12天前
|
JSON IDE Java
鸿蒙开发:json转对象插件回来了
首先,我重新编译了插件,进行了上传,大家可以下载最新的安装包进行体验了,还是和以前一样,提供了在线版和IDE插件版,两个选择,最新的版本,除了升级了版本,兼容了最新的DevEco Studio ,还做了一层优化,就是针对嵌套对象和属性的生成,使用方式呢,一年前的文章中有过详细的概述,这里呢也简单介绍一下。
鸿蒙开发:json转对象插件回来了
|
12天前
|
索引
鸿蒙开发:自定义切换动画实现Swiper层叠滑动效果
customContentTransition不仅仅可以实现平移上的改变,很多的效果,我们都可以实现,比如放大缩小,旋转等等。
鸿蒙开发:自定义切换动画实现Swiper层叠滑动效果
|
8天前
|
JavaScript 前端开发 UED
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发四
本文介绍了Web组件开发与性能优化的相关内容。在Web组件开发部分,涵盖创建组件、设置样式与属性、添加事件和方法以及场景示例,如动态播放视频。性能提升方面,推荐使用数据懒加载、条件渲染替代显隐控制、Column/Row替代Flex、设置List组件宽高及调整cachedCount减少滑动白块等方法,以优化应用性能与用户体验。
31 1
|
8天前
|
JavaScript 前端开发 IDE
鸿蒙开发:了解布局分析ArkUI Inspector
ArkUI Inspector,知名其意,就是UI检查,它可以让开发者在DevEco Studio中快速的查看一个应用在模拟器或者真机上的UI显示效果,并且可以通过查看多次操作后的界面状态,来快速的分析定位UI界面存在的问题。
鸿蒙开发:了解布局分析ArkUI Inspector
|
8天前
|
数据挖掘 测试技术 开发工具
鸿蒙开发:hvigorw,编译构建,实现命令打包
以上呢,就是hvigorw几个常见的命令,主要用于构建不同类型的包,也是接下来流水线打包,几个比较常用的命令,所以拿来重点概述了,当然了hvigorw还有一些常见的命令,大家直接看官网介绍即可,不在多赘述。
鸿蒙开发:hvigorw,编译构建,实现命令打包
|
8天前
|
缓存 开发工具 开发者
鸿蒙开发:了解构建工具hvigorw
hvigorw作为Hvigor的wrapper包装工具,它的主要作用是,支持自动安装Hvigor构建工具和相关插件依赖,以及执行Hvigor构建命令
鸿蒙开发:了解构建工具hvigorw
|
8天前
|
安全 前端开发 开发工具
鸿蒙开发:应用内如何做更新
使用系统的,直接调用检查和显示更新弹窗即可,可以说就两个方法,我们就实现了应用更新的功能,可以说是非常的简单,如果系统的弹窗无法满足您的需求,您可以自定义弹窗,然后实现跳转应用详情页面即可。
鸿蒙开发:应用内如何做更新
|
11天前
|
JavaScript 前端开发 开发者
09.HarmonyOS Next数据驱动UI开发:ForEach与动态渲染完全指南(上)
在现代前端开发中,数据驱动UI已成为主流开发范式。HarmonyOS Next的ArkTS语言和声明式UI框架完美支持这一理念,使开发者能够以更高效、更直观的方式构建复杂应用。
44 1