当前位置: 首页 > article >正文

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

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

1.翻页滚动

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

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

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

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

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

实现代码如下:

@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

样例关键代码如下:

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

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

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

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

代码如下:

@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.小案例

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

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

代码如下:

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')

  }
}


4.事后更新

好啦好啦,我知道大家可能对于最终的效果展示有点不满意,毕竟不够好看嘛,那就把图片给大家换一下,最终结果如下:

至于这么多图片,是不是要一个一个去下?其实不需要的,直接到以下链接,一个Ctrl+S就全部有了,然后选中前面20个丢进media文件夹里,完事:

英雄头像

最终代码:

interface XMNavItem {
  title: string
  icon: ResourceStr // 联合属性 Resource | string
}

@Entry
@Component
struct test_Grid {
  // 数据 只需要渲染,所以没有使用@State 修饰
  navList: XMNavItem[] = [
    { title: '上新精选', icon: $r('app.media.105') },
    { title: '智能家电', icon: $r('app.media.106') },
    { title: '小米众筹', icon: $r('app.media.107') },
    { title: '有品会员', icon: $r('app.media.108') },
    { title: '有品秒杀', icon: $r('app.media.109') },
    { title: '原产地', icon: $r('app.media.110') },
    { title: '生活优选', icon: $r('app.media.111') },
    { title: '6G手机', icon: $r('app.media.112') },
    { title: '小米自营', icon: $r('app.media.113') },
    { title: '茅台酒饮', icon: $r('app.media.114') },
    { title: '鞋服饰品', icon: $r('app.media.115') },
    { title: '家纺餐厨', icon: $r('app.media.115') },
    { title: '食品生鲜', icon: $r('app.media.116') },
    { title: '好惠买', icon: $r('app.media.117') },
    { title: '家具家装', icon: $r('app.media.118') },
    { title: '健康养生', icon: $r('app.media.119') },
    { title: '有品海购', icon: $r('app.media.120') },
    { title: '个护清洁', icon: $r('app.media.121') },
    { title: '户外运动', icon: $r('app.media.123') },
    { title: '3C数码', icon: $r('app.media.124') }
  ]
  // 创建控制器对象
  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')

  }
}


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


http://www.kler.cn/a/385465.html

相关文章:

  • YUM 的使用
  • 【项目开发 | 跨域认证】JSON Web Token(JWT)
  • 数学建模模型算法-Python实现
  • git status 命令卡顿的排查
  • go语言中的log 包详解
  • 【C++】详细介绍模版进阶,细节满满
  • LeetCode题练习与总结:打乱数组--384
  • 无人机干扰与抗干扰,无人机与反制设备的矛与盾
  • 如何解决导入aioredis报错TypeError: duplicate base class TimeoutError的问题(轻松解决,亲测有效)
  • 可视化建模与UML《类图实验报告》
  • WebRTC 环境搭建
  • 【报错解决】使用@SpringJunitConfig时报空指针异常
  • huawei初级网络工程师综合实验
  • 《计算机网络》课后探研题书面报告_了解网络设备
  • 语音识别如何赋能医疗行业:AI技术应用与场景剖析
  • Linux:git的了解和基础使用(保姆级教程)
  • Vue 的代理和环境变量 - 2024最新版前端秋招面试短期突击面试题【100道】
  • Go语言从入门到精通:一站式学习指南
  • Kubernetes中的网络通信
  • CSharp OpenAI
  • 编写第一个 Appium 测试脚本:从安装到运行!
  • 什么是ARM架构和Cortex内核?
  • pytest插件精选:提升测试效率与质量
  • MySQL DATETIME 和 DATE
  • Sql面试题二:请查询出用户连续三天登录的所有数据记录
  • 使用混合 BERT 模型的情感分析分类系统