【HarmonyOS】滚动容器组件与自定义滚动条实践

1,247 阅读4分钟

本文将深入探讨鸿蒙应用开发中的滚动容器组件,并展示如何通过Scroller控制器与ScrollBar组件实现自定义滚动条的效果。

1. 滚动容器组件概览

在鸿蒙应用开发中滚动容器组件主要包括:

  • Scroll:基础滚动容器,支持单个子组件的滚动
  • List:用于展示垂直或水平排列的列表项
  • Grid:提供网格形式的布局,允许内容通过滚动来显示
  • WaterFlow:类似于Grid组件,但是提供了瀑布流式的布局

这些组件支持滚动的基本属性和事件,如滚动方向、滚动条状态、滚动监听等。

2. 滚动的通用属性和通用事件

2.1. 滚动容器组件通常支持以下通用属性:

属性描述
scrollBar设置滚动条的状态,参数类型:BarState
scrollBarColor设置滚动条的颜色
scrollBarWidth设置滚动条的宽度,不支持百分比设置
edgeEffect设置边缘滑动效果,参数类型:EdgeEffect

2.2. 滚动容器组件的通用事件包括:

事件回调描述
onScroll滚动事件回调,返回滚动时的水平和竖直方向偏移量 ,建议使用onDidScroll替代
onDidScroll滚动组件滑动时触发,返回当前帧滑动的偏移量和当前滑动状态
onWillScroll滚动事件回调,滚动组件滚动前触发
onScrollEdge滚动到边缘时触发的事件回调

滚动组件的其他通用属性和事件详见鸿蒙开发文档:滚动组件通用属性和通用事件

2.3. 不同滚动组件设置滚动方向方法

滚动组件设置滚动方式
Scroll组件通过scrollable(value:ScrollDirection) 属性设置Scroll滚动方向
List组件通过listDirection(value:Axis) 属性设置List的排列方式
Grid组件只设置columnsTemplate / rowsTemplate属性,可以设置纵向 / 横向滚动
WaterFlow组件通过layoutDirection属性设置瀑布流布局的主轴方向

3. Scroller 控制器

Scroller可滚动容器组件的控制器,可以将此组件绑定至容器组件,然后通过它控制容器组件的滚动,同一个控制器不可以控制多个容器组件。

@Entry
@Component
struct Index {
  /* 实例化一个Scroller控制器对象 */
  scroller: Scroller = new Scroller()
  
  build() {
    Column(){
      /* 将Scroller控制器绑定不同的组件 */ 
      List({ scroller: this.scroller }){}
      Grid(this.scroller){}
      Scroll(this.scroller){}
      WaterFlow({ scroller: this.scroller }){}
    }
    .width('100%')
    .height('100%')
  }
}

Scroller控制器常用的事件如下:

/* scrollTo: 滑动到指定位置,支持设置动画效果 */
this.scroller.scrollTo(value: {xOffset:number,yOffset:number}): void

/* scrollEdge:滚动到容器边缘	Edge.Top和Start 表现相同滚动到顶部|左端 */ 
this.scroller.scrollEdge(value: Edge, options?: ScrollEdgeOptions): void

/* scrollPage:滚动到下一页或者上一页,next:true -> 上一页  false -> 下一页 */
this.scroller.scrollPage(value: { next: boolean }): void

/*  scrollToIndex: 滑动到指定索引位置,并可选动画效果,适用于Grid、List、WaterFlow等组件 */
this.scroller.scrollToIndex(value: number, smooth?: boolean): void

/* currentOffset: 返回当前滚动偏移量(包括xOffset水平位移量和yOffset垂直位移量) */ 
this.scroller.currentOffset(): OffsetResult
// xOffset水平位移量: this.scroller.currentOffset().xOffset
// yOffset垂直位移量: this.scroller.currentOffset().yOffset

拓展:ListScroller

当需要对 List 组件进行更细致的滚动控制时,使用 ListScroller 会更为合适。

listScroller: ListScroller = new ListScroller()

说明:ListScroller继承自Scroller,具有Scroller的全部方法。

除了Scroller的全部方法,ListScroller特定的方法还有:

  1. getItemRectInGroup:获取ListItemGroup中的ListItem的大小和相对于List的位置。
  2. scrollToItemInGroup:滑动到指定的ListItemGroup中指定的ListItem。
  3. closeAllSwipeActions:将EXPANDED状态的ListItem收起,并设置回调事件。

4. 自定义滚动条实现

ScrollBar组件用于定义滚动条的行为和样式。使用Scroller配合Scroll、List等滚动容器组件使用,可以实现自定义的滚动条。

4.1. 基本使用

ScrollBar(value: ScrollBarOptions)

ScrollBarOptions参数说明:

参数描述
scrollerScroller控制器,可用于与可滚动组件进行绑定。(必填参数)
state?设置滚动条的状态,参数类型:BarState
direction?设置滚动条方向,类型:ScrollBarDirection【默认:ScrollBarDirection.Vertical】

4.2. 配合滚动容器组件使用

  1. 首先实例化一个Scroller控制器对象
  2. 将Scroller控制器分别绑定到滚动容器和ScrollBar组件
  3. 将滚动容器的滚动条隐藏,始终显示ScrollBar的滚动条
  4. 自定义滚动条(ScrollBar的子节点)和可滚动区域(ScrollBar)的样式
@Entry
@Component
struct Index {
  /* 首先,实例化一个Scroller控制器对象 */
  scroller: Scroller = new Scroller()

  build() {
    Column() {
      /* 将Scroller控制器绑定到滚动容器组件 */
      Scroll(this.scroller) {}
        .scrollable(ScrollDirection.Horizontal)	// 设置横向滚动
        .scrollBar(BarState.Off) // 关闭容器组件的滚动条
      
      ScrollBar({ 
        scroller: this.scroller, 	// 绑定Scroller控制器
        state: BarState.On, 	// 设置ScrollBar滚动条始终显示
        direction: ScrollBarDirection.Horizontal	// 设置相同滚动方式
      }) {
        // 自定义滚动条样式...
      }
      // 可滚动区域的行为样式...
    }
    .width('100%')
    .height('100%')
  }
}

5. 扩展:交互效果(待学习)

利用Scroller的事件监听,如onScrollonScrollEdgeonScrollEnd,可以添加滚动条的交互效果,比如滚动到边缘时的回弹效果,或者滚动过程中的动态反馈,后面还可实现的列表的上拉刷新以及下拉加载