ArkUI关于可滚动的容器组件总结

657 阅读5分钟

ArkUI容器

Column -> 纵向排列元素,没有滚动条
Row-> 横向排列元素,没有滚动条
Stack-> 层叠排列元素,没有滚动条
Flex -> 弹性布局通常用来做不规则元素的自动换行,有一些性能问题 没有滚动条
List -> 列表 + 元素外观拥有相同的结构 -> 有滚动条   -> new ListScroller()
Scroll-> 内容超出本身 有滚动条,一个更加轻量级的组件 -> new Scroller()
Tabs  -> 底部导航栏和顶部导航栏 ->  有滚动
Grid  -> 网格布局,用来做很规则的宫格效果 -> 有滚动
Swiper -> 轮播效果 -> 有滚动 -> new SwiperController()
SideBarContainer -> 侧边栏  -> 没有滚动
WaterFlow  -> 瀑布流,垂直方向如果高度不一致可以用它 -> 有滚动 -> new Scroller()

滚动容器控制滚动详解

一,List

使用场景

如果列表很长,需要快速滚动到列表底部或返回列表顶部,就可以使用代码来控制滚动

核心步骤

  1. 创建控制器(ListScroller)对象
  2. 设置给 List 组件
  3. 调用控制器对象的方法,实现滚动

语法

// 1. 创建控制器(ListScroller)对象
listScroller: ListScroller = new ListScroller()
// 2. 设置给 List 组件
List({ space: 20, scroller: this.listScroller }) {
  // ...
}


Button() {
  // ...
}
.onClick(() => {
  // 3. 调用控制器对象的方法,实现滚动
  this.listScroller.scrollToIndex(0)   //可为索引值或ScrollAlign的枚举值
})

滚动事件(当滑动list,组件会自动监控滑动事件,从而返回其索引值)

核心代码

List(){
     // ...
   }
   .onScrollIndex((index: number) => {
     console.log('index:', index)
   })

二,Scroll

核心用法

  1. Scroll 设置尺寸
  2. 设置 子组件(只支持一个子组件)
  3. 设置滚动:
  4. 根据需求调整属性

(1) 竖向滚动:子组件的高度超出 Scroll

(2) 横向滚动:子组件的宽度超出 Scroll,scrollable改为横向滚动

核心步骤

  1. 实例化 Scroller的 控制器
  2. 绑定给 Scroll
  3. 调用 控制器的方法控制滚动,通过控制器的属性获取滚动距离

核心代码

@Entry
@Component
struct ScrollDemo {
  scroller: Scroller = new Scroller()

  build() {
    Column() {
      Scroll(this.scroller) {
        // 内容略
      }
      Row() {
        Button('返回顶部')
          .onClick(() => {
            // 滚到顶部
            this.scroller.scrollEdge(Edge.Top)
          })
 //  this.scroller.scrollEdge(Edge.Top)
//this.scroller.scrollEdge(Edge.Start)
//this.scroller.scrollEdge(Edge.Bottom)
//this.scroller.scrollEdge(Edge.End)

        Button('获取滚动距离')
          .onClick(() => {
            const x = this.scroller.currentOffset().xOffset
            const y = this.scroller.currentOffset().yOffset
            AlertDialog.show({
              message:`x:${x},y:${y}`
            })
          })
      }
    }
  }
}

这里用到了 2 个方法:

  1. scrollEdge:滚动到边缘
  2. currentOffset: 获取当前的偏移量

onWillscroll事件

用法
Scroll(){
  // 内容略
}
  .onWillscroll((x,y)=>{
    // 滚动时 一直触发
    // 可以结合 scroller的currentOffset方法 获取滚动距离
  })

三,Tabs

使用场景

如何导航栏的内容较多,屏幕无法容纳时,可以将他设置为滚动

基本语法

Tabs(){
  // 内容略
}
  .barMode(BarMode.Scrollable)// 滚动
  // .barMode(BarMode.Fixed)// 默认值

Tabs组件的事件(当自定义Taber后,需要自己设定点击后高亮)

核心思想:

1,在[[自定以构建函数设置自定义Taber的基础上]](Tab容器基本用法 属性 1.vertical:设置导航栏水平或者垂直 2.barPosition:调整导航栏的位置,开 - 掘金 (juejin.cn)),手动给定每个Taber索引值以参数的形式绑定

2,以点击事件的形式将选中的索引值赋值给状态变量

3,需要改变的属性以三元形式传递给属性

代码展示

@Entry
@Component
struct Index {
  // 1. ✨✨✨定义一个状态变量,用来存储当前用户选中的tabbar索引
  @State currentIndex: number = 0

  /*
   * 自定义构建函数创建出来的tabbar在做切换高亮功能的步骤:
   * 1. 定义一个状态变量,用来存储当前用户选中的tabbar索引
   * 2. 在调用自定义构建函数的时候,需要传入当前tabbar的索引(固定值),同时要传入点亮的图片路径和正常的图片路径
   * 3. 在自定义构建函数中使用三元表达式来进行高亮功能的处理
   * */

  // 1. 定义构建函数
  @Builder
  tabbarBuilder(title: string, icon: string, selectedIcon: string, index: number) {
    Column({ space: 5 }) {
      // 3. ✨✨✨在自定义构建函数中使用三元表达式来进行高亮功能的处理
      Image(this.currentIndex == index ? $r(selectedIcon) : $r(icon))
        .width(35)
      Text(title)
        // 3. ✨✨✨在自定义构建函数中使用三元表达式来进行高亮功能的处理
        .fontColor(this.currentIndex == index ? Color.Red : Color.Black)
    }
  }

  build() {
    Column() {
      Tabs() {
        TabContent() {
          Text('首页')
            .fontSize(50)
        }
        // 2. ✨✨✨在调用自定义构建函数的时候,需要传入当前tabbar的索引(固定值),同时要传入点亮的图片路径和正常的图片路径
        .tabBar(this.tabbarBuilder('首页', 'app.media.ic_tabbar_icon_0', 'app.media.ic_tabbar_icon_0_selected', 0))

        TabContent() {
          Text('逛')
            .fontSize(50)
        }
        .tabBar(this.tabbarBuilder('逛', 'app.media.ic_tabbar_icon_1', 'app.media.ic_tabbar_icon_1_selected', 1))
      }
      .barPosition(BarPosition.End)
      .animationDuration(0)
      .onChange((index) => {
        this.currentIndex = index
      })

      // ✨✨总结:onChange->触发时机是在切完之后才触发,滑动和点击都能触发
      // .onChange((index) => {
      //   //   index就是被点击的tabbar对应的索引
      //   AlertDialog.show({
      //     message:index.toString()
      //   })
      // })

      // ✨✨总结:onTabBarClick->触发时机是点击tabbar的时候就触发,滑动不能触发
      // .onTabBarClick((index)=>{
      //     AlertDialog.show({
      //       message:index.toString()
      //     })
      // })
    }
    .height('100%')
    .width('100%')

    // .backgroundColor(Color.Pink)

  }
}

四,Grid

设置方式

  1. 水平滚动:设置的是rowsTemplate,Grid的滚动方向为水平方向。
  2. 垂直滚动:设置的是columnsTemplate,Grid的滚动方向为垂直方向

代码控制滚动

核心步骤:

  1. 创建 Scroller 对象
  2. 设置给 Grid
  3. 调用 Scroller 对象的 scrollPage 方法

核心用法

// 创建 Scroller 对象
scroller: Scroller = new Scroller()

// 设置给 Grid
 Grid(this.scroller) {
   // ...
 }

// 通过代码控制
this.scroller.scrollPage({
  next:true // 下一页
  next:false // 上一页
})

五,Swipeer

页面切换

核心步骤 3:

  1. 实例化控制器
  2. 设置给 Swiper
  3. 调用控制器方法

SwiperController对象核心方法

showNext(): void翻至下一页。翻页带动效切换过程,翻页时长可以通过Swiper组件duration和curve指定。
showPrevious(): void翻至上一页。翻页带动效切换过程,翻页时长可以通过Swiper组件duration和curve指定。

代码展示

@Entry
@Component
struct SwiperDemo {
  // 1.创建控制器对象
  controller: SwiperController = new SwiperController()

  build() {
    Column({ space: 10 }) {
      // 2. 设置给 Swiper
      Swiper(this.controller) {
        // 略
      }
      Row() {
        Button('上一页')
          .onClick(() => {
            // 3.调用控制器的方式实现切换效果
            this.controller.showPrevious()
          })
        Button('下一页')
          .onClick(() => {
            this.controller.showNext()
          })
      }

    }
    .width('100%')
    .height('100%')

    // .padding(20)
  }
}

六,WaterFlow

使用场景

瀑布流容器,由“行”和“列”分割的单元格所组成,通过容器自身的排列规则,将不同大小的“项目”自上而下,如瀑布般紧密布局

核心

以RowsTemplate实现水平滚动 以ColumnsTemplate实现垂直滚动

scroll注意

可滚动组件的控制器,与可滚动组件绑定。

说明:

不允许和其他滚动类组件,如:ListGridScroll等绑定同一个滚动控制对象。