HarmonyOS实战:Tab顶部滑动悬停功能实现

前言

日常开发过程中,遇到这种 Scroll 嵌套 List 列表滑动顶部悬停的场景十分常见,在鸿蒙开发时也正好实现了这个功能,本篇文章将带你一步步实现 Tab 顶部悬停的效果,建议点赞收藏!

实现效果

先看本文的最终实现效果如下:

alt

需求分析

  • 当整体向上滑动时,优先 Scroll 向上滑动。
  • 当整体向下滑动时,优先 Scroll 向下滑动。

技术实现

  1. 首先需要实现基础页面布局,直接使用 Scroll 嵌套 List 布局。将 List 用 Tab 布局嵌套起来。
 Scroll(this.scroller) {
          Column() {
            Text("内容")
              .textAlign(TextAlign.Center)
              .fontColor(Color.White)
              .backgroundColor(this.themColor.value)
              .width('100%')
              .height('40%')

            Tabs({ barPosition: BarPosition.Start }) {
              TabContent() {
                Column() {
                  Refresh({refreshing:false,friction:0,offset:0}){
                    List({ space: 10, scroller: this.scrollerForList }) {
                      ForEach(this.list, (item: string) => {
                        ListItem() {
                          Text('ListItem' + item)
                            .width('100%')
                            .height('100%')
                            .borderRadius(15)
                            .fontSize(24)
                            .textAlign(TextAlign.Center)
                            .backgroundColor(Color.White)
                        }
                        .width('100%')
                        .height(100)
                      }, (item: string) => item)
                    }
                   
                  .pullToRefresh(true)
                }

              }.tabBar('你好')

              TabContent() {
                Column().width('100%').height('100%').backgroundColor('#007DFF')
              }.tabBar('好的')

            }
            }

这里布局比较简单,使用两个 tab 用来切换布局。外层使用 Scroll 包裹,其中一个 tab 的里面使用 List 布局。相信这对大多人来说没有什么难度。

  1. 搭建好基础布局后,开始处理滑动冲突问题。根据实现效果来看,每次都是让外层的 Scroll 优先滑动,需要给 List 增加拦截处理,让每次滑动优先外层 Scroll 布局滑动,这里使用nestedScroll 属性的NestedScrollMode.PARENT_FIRST,即优先父布局滑动。
 .nestedScroll({
                      scrollForward: NestedScrollMode.PARENT_FIRST,
                      scrollBackward: NestedScrollMode.PARENT_FIRST
                    })
  1. 这时不管怎么上下滑动,里面的 List 都不会滑动,只让外层的 Scroll 组件滑动。接下来处理 List 的滑动事件。
  2. 首先定义一个枚举类型,用来标记滑动位置。
enum ScrollPosition {
  top,
  center,
  bottom
}
  1. 接下来分别实现 List 的 onReachStart,onReachEnd,onScrollFrameBegin 三个方法。这个比较容易理解,滑动道顶部时,记录当前位置为顶部,滑动底部时,记录当前位置为底部,onScrollFrameBegin 表示滑动过程中的回调,根据当前滑动位置和滑动偏移量来记录是否继续滑动。
                    .onReachStart(() => {
                      this.listPosition = ScrollPosition.top
                    })
                    .onReachEnd(() => {
                      this.listPosition = ScrollPosition.bottom
                    })
                    .onScrollFrameBegin((offset: number, state: ScrollState) => {
                      if ((this.listPosition == ScrollPosition.top && offset <=0)||(this.listPosition == ScrollPosition.bottom && offset>=0)) {
                        return {offsetRemain :offset}
                      }
                      this.listPosition = ScrollPosition.center
                      return {offsetRemain:offset}
                    })
  1. 再看外层 Scroll 的滑动方法监听,同样也是分别实现这三种方法,不过注意onScrollFrameBegin 里面返回值和 List 的不同,当 Scroll 滑动到底部活着顶部时,Scroll 不再滑动,注意看返回值为 0,否则 Scroll 才滑动。
 .onReachStart(() => {
          this.listPosition = ScrollPosition.top
        })
        .onReachEnd(() => {
          this.listPosition = ScrollPosition.bottom
        })
        .onScrollFrameBegin((offset: number, _: ScrollState) => {
          if ((this.listPosition == ScrollPosition.top && offset <= 0) || (
            this.listPosition == ScrollPosition.bottom && offset >= 0)
          ) {
            return { offsetRemain: 0 }
          }
          //不在底部
          this.listPosition = ScrollPosition.center
          return { offsetRemain: offset }
        })
  1. 根据 List 组件和 Scroll 组件的滑动监听,用来判断哪种状态下 Scroll 优先滑动,当 Scroll 滑动到底部活顶部时,通过返回值赋值为 0 ,阻止 Scroll 滑动,将滑动事件交个内部的 List 滑动。注意 List 通过设置nestedScroll 将滑动事件优先让外层 Scroll 处理。所以一开始是外层的 Scroll 先滑动。

总结

本文主要是根据实际需求实现的滑动效果,每次都优先让 Scroll 滑动,还有更多的滑动场景都可以用这种方式的思路解决,主要通过不同的判断条件即可实现。例如向下滑动时优先让 List 滑动,然后再让 Scroll 滑动。学会的小伙伴赶紧动手试试吧!

#鸿蒙##harmonyos#
全部评论

相关推荐

机械打工仔:第一位颇有孟德之志
点赞 评论 收藏
分享
06-13 17:33
门头沟学院 Java
顺序不记了,大致顺序是这样的,有的相同知识点写分开了1.基本数据类型2.基本数据类型和包装类型的区别3.==和equals区别4.ArrayList与LinkedList区别5.hashmap底层原理,put操作时会发生什么6.说出几种树型数据结构7.B树和B+树区别8.jvm加载类机制9.线程池核心参数10.创建线程池的几种方式11.callable与runnable区别12.线程池怎么回收线程13.redis三剑客14.布隆过滤器原理,不要背八股,说说真正使用时遇到了问题没有(我说没有,不知道该怎么回答了)15.堆的内存结构16.自己在写项目时有没有遇见过oom,如何处理,不要背八股,根据真实经验,我说不会17.redis死锁怎么办,watchdog机制如何发现是否锁过期18.如何避免redis红锁19.一个表性别与年龄如何加索引20.自己的项目的QPS怎么测的,有没有真正遇到大数量表21.说一说泛型22.springboot自动装配原理23.springmvc与springboot区别24.aop使用过嘛?动态代理与静态代理区别25.spring循环依赖怎么解决26.你说用过es,es如何分片,怎么存的数据,1000万条数据怎么写入库中27.你说用limit,那么在数据量大之后,如何优化28.rabbitmq如何批次发送,批量读取,答了延迟队列和线程池,都不对29.计网知不知道smtp协议,不知道写了对不对,完全听懵了30.springcloud知道嘛?只是了解反问1.做什么的?短信服务,信息量能到千万级2.对我的建议,基础不错,但是不要只背八股,多去实际开发中理解。面试官人不错,虽然没露脸,但是中间会引导我回答问题,不会的也只是说对我要求没那么高。面完问我在济宁生活有没有困难,最快什么时候到,让人事给我聊薪资了。下午人事打电话,问我27届的会不会跑路,还在想办法如何使我不跑路,不想扣我薪资等。之后我再联系吧,还挺想去的😭,我真不跑路哥😢附一张河科大幽默大专图,科大就是大专罢了
查看30道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务