鸿蒙进阶篇-网格布局 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')

  }
}

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

相关推荐
前端百草阁8 分钟前
【TS简单上手,快速入门教程】————适合零基础
javascript·typescript
彭世瑜9 分钟前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
FØund40410 分钟前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
Backstroke fish10 分钟前
Token刷新机制
前端·javascript·vue.js·typescript·vue
小五Five11 分钟前
TypeScript项目中Axios的封装
开发语言·前端·javascript
小曲程序11 分钟前
vue3 封装request请求
java·前端·typescript·vue
临枫54112 分钟前
Nuxt3封装网络请求 useFetch & $fetch
前端·javascript·vue.js·typescript
RAY_CHEN.13 分钟前
vue3 pinia 中actions修改状态不生效
vue.js·typescript·npm
酷酷的威朗普13 分钟前
医院绩效考核系统
javascript·css·vue.js·typescript·node.js·echarts·html5
前端每日三省13 分钟前
面试题-TS(八):什么是装饰器(decorators)?如何在 TypeScript 中使用它们?
开发语言·前端·javascript