HarmonyOS应用开发之滚动容器Scroll

滚动容器(Scroll)

Scroll表示可滚动的容器组件,当子组件的布局尺寸超过父组件的尺寸时,内容可以滚动。

!warning

注意两个要点:

  1. Scroll子组件的布局尺寸超过父组件尺寸时,才可以滚动
  2. Scroll只能有一个子组件

基本使用

如图所示,在Column中包含10Text文本,每个Text文本的高度为100,间距为10

Scroll内子组件的总高度大于Scroll父组件的高度,所以可以滚动。

代码如下

ts 复制代码
@Entry
@Component
struct Index {
  @State array: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  build() {
    Column(){
      Scroll(){
        Column({ space: 20 }) {
          ForEach(this.array, (item: number) => {
            Text(`${item}`)
              .width("100%")
              .textAlign(TextAlign.Center)
              .width("100%")
              .height(100)
              .borderRadius(15)
              .backgroundColor(Color.White)
          })
        }
        .padding(10)
      }
    }.width("100%")
    .height("100%")
    .backgroundColor("#dedede")
  }
}

关闭滚动条

通过.scrollBar(barState: BarState)设置滚动条的显示模式

  • BarState.Off 关闭滚动条
  • BarState.On 显示滚动条
  • BarState.Auto 滑动时显示滚动条,3秒后消失
scss 复制代码
Scroll(){
    ...
}.scrollBar(BarState.Off)   //关闭滚动条

滚动方向

通过.scrollable(value: ScrollDirection)属性用来设置Scroll的滚动方向。

参数

  • ScrollDirection.Vertical 垂直滚动
  • ScrollDirection.Horizontal 水平滚动

示例:在水平方向显示10个Text,沿水平方向滚动。

代码如下

ts 复制代码
@Entry
@Component
struct Index {
  @State array: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  build() {
    Column(){
      Scroll(){
        Row({ space: 20 }) {
          ForEach(this.array, (item: number) => {
            Text(`${item}`)
              .width("100%")
              .textAlign(TextAlign.Center)
              .width(100)
              .height(100)
              .borderRadius(15)
              .backgroundColor(Color.White)
          })
        }.padding(10)
      }
      .scrollBar(BarState.Off)	//关闭滚动条
      .scrollable(ScrollDirection.Horizontal) //水平滚动方向
    }.width("100%")
    .height(120)
    .backgroundColor("#dedede")
  }
}

滚动条样式

通过scrollBarWidth(20)和scrollBarColor(Color.Red)设置滚动条的宽度与颜色。

ts 复制代码
Scroll(){
       ...
}
.scrollBar(BarState.Auto)
.scrollable(ScrollDirection.Horizontal) //滚动方向
.scrollBarWidth(10)	//滚动条宽度
.scrollBarColor(Color.Red) //滚动条颜色

滚动控制器

通过给Scroll配置Scroller滚动控制器,来控制Scroll的滚动。

Scroller有如下方法控制Scroll滚动

  • scrollEdge(value: Edge, options?: ScrollEdgeOptions | undefined) 滚动到容器边缘
  • scrollTo(options: ScrollOptions) 滚动到指定位置
    • xOffset: 水平偏移量(相对于容器开始位置)
    • yOffset: 垂直偏移量(相对于容器开始位置)
  • scrollBy(dx: Length, dy: Length) 滚动指定距离。
    • dx: 水平滚动距离(相对于当前位置)
    • dy: 垂直滚动距离(相对于当前位置)

如下图所示,点击按钮时控制Scroll滚动到底部、顶部、中间位置,此时就需要用到Scroller滚动控制器。

代码如下

ts{5,9,30,34,44-47} 复制代码
@Entry
@Component
struct Index {
  @State array: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  private scorller: Scroller = new Scroller()

  build() {
    Column() {
      Scroll(this.scorller) {
        Column({ space: 20 }) {
          ForEach(this.array, (item: number) => {
            Text(`${item}`)
              .width("100%")
              .textAlign(TextAlign.Center)
              .width("100%")
              .height(100)
              .borderRadius(15)
              .backgroundColor(Color.White)
          })
        }.padding(10)
      }
      .layoutWeight(1)
      .scrollBar(BarState.Auto)
      .scrollable(ScrollDirection.Vertical) //滚动方向
      .scrollBarWidth(10)
      .scrollBarColor(Color.Red)

      Row() {
        Button("到底部").onClick(() => {
          this.scorller.scrollEdge(Edge.Bottom)
        })

        Button("到顶部").onClick(() => {
          this.scorller.scrollEdge(Edge.Top)
        })

        Button("到中间").onClick(() => {
          animateToImmediately({
            duration: 300,
            playMode: PlayMode.Normal,
            curve: Curve.Ease
          }, () => {
            //滑动到指定位置
            this.scorller.scrollTo({
              xOffset: 0,
              yOffset: 300
            })
          })
        })

        Button("滚动一段").onClick(() => {
          //滑动到指定位置
          animateToImmediately({
            duration: 300,
            playMode: PlayMode.Normal,
            curve: Curve.Ease
          }, () => {
            //滑动到指定位置
            this.scorller.scrollBy(0, 100)
          })
        })
      }.width("100%")
      .height(200)
      .alignItems(VerticalAlign.Center)
      .justifyContent(FlexAlign.SpaceEvenly)

    }.width("100%")
    .height("100%")
    .backgroundColor("#dedede")
  }
}

滚动监听

有时候需要监听当前Scroll滚动的状态,根据状态做出相应的处理,此时需要用到滚动监听。

  • onDidScroll(handler: ScrollOnScrollCallback) 滚动事件回调,Scroll滚动时触发。返回当前帧滚动的偏移量和当前滚动状态。
    • xOffset: 每一帧的水平偏移量
    • yOffset: 每一帧的垂直偏移量

触发该事件的条件:

  1. 滚动组件触发滚动时触发,支持键鼠操作等其他触发滚动的输入设置。
  2. 通过滚动控制器API接口调用。
  3. 越界回弹。

示例代码: 监听Scroll滚动的距离,当向下滚动200像素时,弹出提示,效果如下图所示

代码如下

ts 复制代码
import { promptAction } from '@kit.ArkUI'

@Entry
@Component
struct Index {
  @State array: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  private scorller: Scroller = new Scroller()
  //记录相对于Scroll开始位置的偏移量
  private yOffset_total: number = 0

  build() {
    Column() {
      Scroll(this.scorller) {
        Column({ space: 20 }) {
          ForEach(this.array, (item: number) => {
            Text(`${item}`)
              .width("100%")
              .textAlign(TextAlign.Center)
              .width("100%")
              .height(100)
              .borderRadius(15)
              .backgroundColor(Color.Pink)
          })
        }.padding(10)
      }
      .layoutWeight(1)
      .scrollBar(BarState.Auto)
      .scrollable(ScrollDirection.Vertical) 
      .scrollBarWidth(10)
      .scrollBarColor(Color.Red)
      .backgroundColor("#dedede")
       //监听Scorll滚动,计算总偏移量
      .onDidScroll((xOffset: number, yOffset) => {
        this.yOffset_total += yOffset
        if (this.yOffset_total >= 200 && yOffset > 0) {
          promptAction.openToast({ message: "滚动到200了" })
        }
        console.log("偏移量:" + this.yOffset_total)
      })
    }.width("100%")
    .height("100%")
  }
}

在滚动时,监听滚动偏移量并打印,如下图所示,总偏移量yOffset_total是依次递增的。

到此,Scroll的使用以及Scroller滚动控制器就介绍完了。Scroller滚动控制器在其他可滚动组件也同样适用。

对鸿蒙感兴趣的同学,免费考取鸿蒙开发者认证

相关推荐
贾伟康7 小时前
【口算王|20】HarmonyOS ArkTS AppGallery 发布复查实战:核对包名、版本、设备、素材和离线声明
harmonyos·arkts·appgallery·应用发布·发布审核
ChinaDragon11 小时前
HarmonyOS:Web使用Dsbridge与JavaScript完成交互
harmonyos
思录Echo14 小时前
自助易AI数字人外挂技术剖析|如何解决政企智能客服的多端适配难题?
人工智能·华为·harmonyos
方白羽15 小时前
为什么 Android 非要用 Intent 传值?
android·ios·harmonyos
不爱吃糖的程序媛21 小时前
从 0 到 1:react-native-transformer-text-input 鸿蒙化适配实录
react native·transformer·harmonyos
不爱吃糖的程序媛21 小时前
React Native 三方库鸿蒙适配实战:react-native-emoji-popup(Fabric 自定义组件)从 0 到 1
react native·harmonyos·fabric
贾伟康21 小时前
【口算王|19】HarmonyOS ArkTS 回归测试实战:覆盖启动、空数据、异常输入和重复点击
软件测试·harmonyos·arkts·回归测试·hypium
贾伟康21 小时前
【句匠|09】HarmonyOS ArkTS 学习统计实战:汇总正确率、连续学习和薄弱类型
harmonyos·arkts·appstorage·学习统计·本地统计
贾伟康1 天前
【口算王|17】HarmonyOS ArkTS 亮暗色与视觉令牌实战:集中颜色、间距和交互状态避免页面割裂
harmonyos·arkts·arkui·深色模式·ui设计
搬砖的kk1 天前
从 0 到 1:react-native-screenshot-aware 鸿蒙适配实战(RNOH 0.84)
react native·华为·harmonyos