鸿蒙进阶篇-网格布局 Grid/GridItem(二)

hello大家好,这里是鸿蒙开天组,今天让我们来继续学习鸿蒙进阶篇-网格布局 Grid/GridItem,上一篇博文我们已经学习了固定行列、合并行列和设置滚动,这一篇我们将继续学习Grid的用法,实现翻页滚动、自定义滚动条样式,并实现一个小案例。

1.翻页滚动

到这里就需要用到控制器对象了,核心步骤如下:

  1. 创建 Scroller 对象(控制器对象)
  2. 设置给 Grid
  3. 调用 Scroller 对象的 scrollPage 方法
TypeScript 复制代码
// 1.创建 Scroller 对象(new 关键字,调用Scroller函数,返回一个Scroller的对象)
scroller: Scroller = new Scroller()

//  2.设置给 Grid:这个属性可选,所以之前不设置也不会报错
 Grid(this.scroller) {
   // ...
 }

// 3.调用 Scroller 对象的  scrollPage 方法即可实现滚动
this.scroller.scrollPage({
  next:true // 下一页
  next:false // 上一页
})

属于一看就会的代码,于是实现一个翻页滚动效果,当然也可以左右滑动啦:

实现代码如下:

TypeScript 复制代码
@Entry
@Component
struct test_Grid {
  // 控制器对象,不是状态属性,不需要添加任何修饰符
  scroller: Scroller = new Scroller()

  build() {
    Column() {
      Text('控制器-实现翻页滚动')
        .fontSize(20)
        .fontWeight(900)
        .padding(10)
      Grid(this.scroller) {
        ForEach(Array.from({ length: 200 }), (item: number, index: number) => {
          GridItem() {
            Text(index + 1 + '').fontColor(Color.Orange)
          }
          .backgroundColor(Color.Green)
          .width('25%')
        })
      }
      .padding(10)
      .height(450)
      .rowsGap(10)
      .columnsGap(10)
      .rowsTemplate('1fr 1fr 1fr 1fr')

      Row() {
        Button('上一页')
          .width(100)
          .onClick(() => {
            // 上一页
            this.scroller.scrollPage({ next: false })

          })
        Button('下一页')
          .width(100)
          .onClick(() => {
            // 下一页
            this.scroller.scrollPage({ next: true })
          })
      }
      .width('100%')
      .justifyContent(FlexAlign.SpaceAround)
    }
  }
}

2.自定义滚动条

滚动条组件ScrollBar,用于配合可滚动组件使用,如List、Grid、Scroll,如果默认的滚动条外观无法满足需求,我们还可以自定义滚动条:

第一步 :首先通过 GridscrollBar 属性关闭滚动条

|-----------|----------|------------------------------------------------------------------------------|
| 属性名 | 类型 | 说明 |
| scrollBar | BarState | 设置滚动条状态。 默认值:BarState.auto BarState.off 关闭 BarState.on 常驻 BarState.auto 按需显示 |

第二步 :使用ScrollBar组件自定义滚动条

|-----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|--------------------------------------------------------|
| 参数名 | 参数类型 | 必填 | 参数描述 |
| scroller | Scroller | 是 | 可滚动组件的控制器。用于与可滚动组件进行绑定。 |
| direction | ScrollBarDirection | 否 | 滚动条的方向,控制可滚动组件对应方向的滚动。 默认值:ScrollBarDirection.Vertical |
| state | BarState | 否 | 滚动条状态。 默认值:BarState.Auto |

样例关键代码如下:

TypeScript 复制代码
// 创建控制器对象
scroller: Scroller = new Scroller()

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

// 设置给 ScrollBar 组件
// 和 Grid 设置的是同一个
ScrollBar({
  scroller: this.scroller,
  direction: ScrollBarDirection.Horizontal // 方向
}) {
  // 滚动内容 设置外观即可
  Text()
}
// 设置外观

在上面代码的基础上,先来一个看着丑但足够显眼的滚动条:

代码如下:

TypeScript 复制代码
@Entry
@Component
struct test_Grid {
  // 控制器对象,不是状态属性,不需要添加任何修饰符
  scroller: Scroller = new Scroller()

  build() {
    Column() {
      Text('控制器-实现翻页滚动')
        .fontSize(20)
        .fontWeight(900)
        .padding(10)
      Grid(this.scroller) {
        ForEach(Array.from({ length: 200 }), (item: number, index: number) => {
          GridItem() {
            Text(index + 1 + '').fontColor(Color.Orange)
          }
          .backgroundColor(Color.Green)
          .width('25%')
        })
      }
      .padding(10)
      .height(450)
      .rowsGap(10)
      .columnsGap(10)
      .rowsTemplate('1fr 1fr 1fr 1fr')
      .scrollBar(BarState.Off)

      // 自定义滚动条
      ScrollBar({
        scroller: this.scroller, // 和 Grid 同一个控制器对象
        direction: ScrollBarDirection.Horizontal,
      }) {
        Text()
          .width(40)
          .height(20)
          .backgroundColor(Color.Orange)
      }
      .width(200)
      .height(20)
      .backgroundColor(Color.Red)


      Row() {
        Button('上一页')
          .width(100)
          .onClick(() => {
            // 上一页
            this.scroller.scrollPage({ next: false })

          })
        Button('下一页')
          .width(100)
          .onClick(() => {
            // 下一页
            this.scroller.scrollPage({ next: true })
          })
      }
      .width('100%')
      .justifyContent(FlexAlign.SpaceAround)
    }
  }
}

3.小案例

最后,使用刚刚学习的自定义滚动条来完成滚动导航的滚动条:

嘿!一个丝滑又漂亮的滚动条就出来啦,注意咱们这里主要是做的滚动条,具体图标填充,可以自行使用其他图片测试哦!

代码如下:

TypeScript 复制代码
interface XMNavItem {
  title: string
  icon: ResourceStr // 联合属性 Resource | string
}

@Entry
@Component
struct test_Grid {
  // 数据 只需要渲染,所以没有使用@State 修饰
  navList: XMNavItem[] = [
    { title: '上新精选', icon: $r('app.media.foreground') },
    { title: '智能家电', icon: $r('app.media.background') },
    { title: '小米众筹', icon: $r('app.media.startIcon') },
    { title: '有品会员', icon: $r('app.media.startIcon') },
    { title: '有品秒杀', icon: $r('app.media.app_icon') },
    { title: '原产地', icon: $r('app.media.foreground') },
    { title: '生活优选', icon: $r('app.media.background') },
    { title: '6G手机', icon: $r('app.media.startIcon') },
    { title: '小米自营', icon: $r('app.media.startIcon') },
    { title: '茅台酒饮', icon: $r('app.media.app_icon') },
    { title: '鞋服饰品', icon: $r('app.media.app_icon') },
    { title: '家纺餐厨', icon: $r('app.media.app_icon') },
    { title: '食品生鲜', icon: $r('app.media.app_icon') },
    { title: '好惠买', icon: $r('app.media.app_icon') },
    { title: '家具家装', icon: $r('app.media.app_icon') },
    { title: '健康养生', icon: $r('app.media.app_icon') },
    { title: '有品海购', icon: $r('app.media.app_icon') },
    { title: '个护清洁', icon: $r('app.media.app_icon') },
    { title: '户外运动', icon: $r('app.media.app_icon') },
    { title: '3C数码', icon: $r('app.media.app_icon') }
  ]
  // 创建控制器对象
  scroller: Scroller = new Scroller()

  build() {
    Column() {
      Text('小米有品')
        .fontSize(20)
        .fontWeight(900)
        .padding(10)
      Grid(this.scroller) {
        ForEach(this.navList, (item: XMNavItem) => {
          GridItem() {
            Column() {
              Image(item.icon)
                .width('80%')
              Text(item.title)
                .fontSize(12)
            }
            .height('100%')
          }
          .width('20%')
        })
      }
      .rowsTemplate('1fr 1fr')
      .height(160)
      .width('100%')
      .backgroundColor(Color.White)
      .borderRadius(5)
      .padding({ bottom: 10 })
      .scrollBar(BarState.Off) // 关闭滚动条

      // 自定义滚动条
      ScrollBar({
        scroller: this.scroller,
        direction: ScrollBarDirection.Horizontal, // 横向滚动
        state: BarState.On // 持续显示
      }) {
        Text()
          .height(5)
          .width(20)
          .backgroundColor(Color.Orange)
          .borderRadius(3)
      }
      .width(50)
      .height(5)
      .backgroundColor('#e5e5e5')
      .borderRadius(3)
      .offset({ y: -10 })

    }
    .width('100%')
    .height('100%')
    .padding(10)
    .backgroundColor('#f5f5f5')

  }
}

好了,今天的分享到这里为止,感谢阅读,欢迎点赞收藏支持鼓励下!

相关推荐
一只栖枝1 小时前
华为 HCIE 大数据认证中 Linux 命令行的运用及价值
大数据·linux·运维·华为·华为认证·hcie·it
加班是不可能的,除非双倍日工资3 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi4 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip4 小时前
vite和webpack打包结构控制
前端·javascript
excel5 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
阿华的代码王国5 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼5 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jimmy5 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
zhanshuo5 小时前
在鸿蒙里优雅地处理网络错误:从 Demo 到实战案例
harmonyos
zhanshuo5 小时前
在鸿蒙中实现深色/浅色模式切换:从原理到可运行 Demo
harmonyos