HarmonyOS应用开发( Beta5.0)一杯冰美式的时间“拿捏Grid组件”

news2024/12/23 22:59:45

常见情形

在很多手机商城的页面中会出现类似网格状一样的情况,例如:

  1. 京东

​这里呢是采用Grid组件中的控制滚动,里面的rowsTemplate属性为一行且不对列的行数属性进行操作,这样的话就可以控制水平滑动了。

2.淘宝

​ 这里就是极其简单的2*4的网格布局。

3.hao123

​ 这里类似淘宝。

基本用法

Grid组件适用于布局由很多的行和列所组成、行列部分需要合并、需要滚动的场景。如下:

组件结构:

Grid(){
    GridItem(){
        //展示的内容
    }
    GridItem(){
        //展示的内容
    }
}

说明:1.Grid的子组件必须是GridItem组件,展示的内容放在GridItem中

​ 2.GridItem只有一个子组件,跟初始代码块中build()一样,有且只能有一个子组件

​ 3.Grid组件若是没有设置宽高,会默认适应其父组件的尺寸

样例:

@Entry
@Component
struct Index {
  nums: number[] = Array.from({ length: 10 })//定义数组

  build() {
    Column() {
      Grid() {
        ForEach(this.nums, (item: number, index: number) => {//ForEach循环渲染
          GridItem() {
            Text(index.toString())//调用索引对GridItem进行编号
              .fontSize(30)
              .padding(5)
              .backgroundColor(Color.Yellow)
          }
        })
      }
    }
    .width("100%")
    .height("100%")
  }

运行结果:

由于没有对齐进行行列分布,所以所有GridItem()内的内容都展示在一行,下面让我来介绍一下Grid组件中常用的属性

基础属性

1.columnsTemplate 该属性用于设置网格布局的列数量

示例写法: .columnsTemplate('1fr 1fr 2fr')

从中fr出现的次数表示分成了几列,前面的数字则表示当前列所占用的份数

2.rowsTemplate 该属性用于设置网格布局的行数量

示例写法: .rowsTemplate('1fr 1fr 2fr')

从中fr出现的次数表示分成了几行,前面的数字则表示当前行所占用的份数

3.columnsGap 该属性用于控制列与列之间的间距

示例写法: .columnsGap(10)

4.rowsGap 该属性用于控制行与行1之间的间距

示例写法: .rowsGap(10)

练一练:

@Entry
@Component
struct TestPage {
  build() {
    Grid() {
      this.GridItemBuilder('1', Color.Blue)
      this.GridItemBuilder('2', Color.Blue)
      this.GridItemBuilder('3', Color.Blue)
      this.GridItemBuilder('4', Color.Blue)
      this.GridItemBuilder('5', Color.Blue)
      this.GridItemBuilder('6', Color.Blue)
    }
    .rowsTemplate('1fr 1fr 1fr')
    .columnsTemplate('1fr 2fr 1fr')
    .rowsGap(10)
    .columnsGap(10)
    .width('100%')
    .height(300)
  }

  @Builder
  GridItemBuilder(title: string, bgColor: ResourceColor) {
    GridItem() {
      Text(title)
        .fontColor(Color.White)
        .fontSize(30)
    }
    .backgroundColor('#0094ff')
  }
}

这边解答采用了@Builder将GridItem进行了封装,这样看起来清晰很多。

合并行列

像下面左边的图片我们可以通过分配列占的份数来让他变宽,但下面右边的图片中的合并应该怎么样来做呢?这边则需要用到一些GridItem属性,让我来为大家讲解。

GridItem属性:

  1. rowStart(number) 指定当前元素的起始行号

  2. rowEnd(number) 指定当前元素的终点行号

  3. columnStart(number) 指定当前元素的起始列号

  4. columnEnd (number) 指定当前元素的终点行号

    !!!这里的起始行号和列号是从1开始,比如你写的是四列,那么列号就是1,2,3,4

首先,我们先对所有元素进行编号,我这里就是直接用forEach中索引标记

然后,我们需要通过索引找到我们需要进行合并网格,这边我拿索引为2和3的网格举个例子。显然易见,这两个网格是列合并,行是没有变化,所以只需要找到其中一个,添加起始列号和终点列号就可以完成合并。

以此类推,索引4和8的网格是行合并,起始和终点行号分别为2,3,索引8,9,10就是类似2,3的列合并,起始和终点列号为2和4。

完整代码:

@Entry
@Component
struct GridPage03 {
  nums: number[] = Array.from({ length: 12 })

  build() {
    Grid() {
      ForEach(this.nums, (item: number, index: number) => {
        if (index === 2) {
          GridItem() {
            Text(index + '')
              .fontColor(Color.White)
              .fontSize(30)
          }
          .backgroundColor('#9dc3e6')
          .columnStart(3)
          .columnEnd(4)
        } else if (index === 3) {
          GridItem() {
            Text(index + '')
              .fontColor(Color.White)
              .fontSize(30)
          }
          .backgroundColor('#9dc3e6')
          .rowStart(2)
          .rowEnd(3)
        } else {
          GridItem() {
            Text(index + '')
              .fontColor(Color.White)
              .fontSize(30)
          }
          .backgroundColor('#9dc3e6')
        }

      })
    }
    .columnsTemplate('1fr 1fr 1fr 1fr')
    .rowsTemplate('1fr 1fr 1fr')
    .width('100%')
    .height(260)
    .rowsGap(10)
    .columnsGap(10)
    .padding(10)
  }
}

第二种方法:GridLayoutOptions

这个接口非常的新,也是刚更新不久,官方文档:developer.huawei.com/consumer/cn…

我们先来看下最常用的两个参数吧!

  1. regularSize[number,number] 大小规则的GridItem在Grid中所占的行数和列数 ,目前呢只支持一行一列,也就是[1,1]

  2. onGetRectByIndex 类型:(index:number)=>[rowStart,columnStart,rowSpan,columnSpan]

    这里就是先通过索引找对应的GridItem,然后通过中括号里的四个参数来进行合并行列。

    1. rowStart 表达的含义跟第一种方法一样,表示当前元素行起始位置
    2. columnStart 也是如此,表示当前元素列起始位置
    3. rowSpan 这里Span表示跨度的意思,所以就是占用的行数
    4. columnSpan 表示占用的列数

完整代码:

@Entry
@Component
struct Index {
  @State nums: string[] = ['0', '1', '2', '3', '4', '5']
  layoutOption: GridLayoutOptions = {
    regularSize: [1, 1],
    onGetRectByIndex: (index: number) => {
      if (index == 0) {
        return [0, 0, 1, 1]
      } else if (index == 1) {
        return [0, 1, 2, 2]
      } else if (index == 2) {
        return [0, 3, 3, 3]
      } else if (index == 3) {
        return [3, 0, 3, 3]
      } else if (index == 4) {
        return [4, 3, 2, 2]
      } else {
        return [4, 5, 2, 1]
      }
    }
  }

  build() {
    Grid(undefined, this.layoutOption) {
      ForEach(this.nums, (item: string) => {
        GridItem() {
          Text(item)
            .fontSize(16)
            .backgroundColor('#f9ce93')
            .width('100%')
            .height("100%")
            .textAlign(TextAlign.Center)
        }
        .height("100%")
        .width('100%')
      })
    }
    .columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr')
    .rowsTemplate('1fr 1fr 1fr 1fr 1fr 1fr')
    .columnsGap(10)
    .rowsGap(10)
    .width('90%')
    .backgroundColor('#fcf0e2')
    .height(300)
  }
}

设置滚动

像文案开头京东那种就是可以滑动的网格布局,这里原理也是非常的简单,Grid中滑动不需要用到scroller控制器,只需要以下操作。

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

!!!这两不要同时设置,不然就滑动不了了

试一试:

@Entry
@Component
struct Day01_09_Grid05 {
  // 长度为 10 每一项都为 undefined 的数组
  list: string[] = Array.from({ length: 30 })

  build() {
    Column() {
      Grid() {
        ForEach(this.list, (item: string, index) => {
          GridItem() {
            Text((index + 1).toString())
              .newExtend()
          }
          .padding(5)
          .height('30%')
          .width('25%')
        })

      }
      .columnsTemplate('1fr 1fr 1fr') // 竖向滚动
      // .rowsTemplate('1fr 1fr 1fr') // 横向滚动
      .rowsGap(10)
      .width('100%')
      .height(300)
      .border({ width: 1 })
      .padding(5)
    }
    .width('100%')
    .height('100%')
  }
}

@Extend(Text)
function newExtend() {
  .backgroundColor('#0094ff')
  .width('100%')
  .height('100%')
  .fontSize(30)
  .fontColor(Color.White)
  .textAlign(TextAlign.Center)
}

当然大家会发现我们的滚动条有点丑,先别急我下面会讲!!

用代码控制滚动

这里很明显是用控制器和按钮来控制滑动了,先讲一下核心步骤吧。

  1. 创建 Scroller 对象

  2. 设置给 Grid

  3. 调用 Scroller 对象的 scrollPage 方法

    // 创建 Scroller 对象
    scroller: Scroller = new Scroller()
    
    // 设置给 Grid
     Grid(this.scroller) {
       // ...
     }
    
    // 通过代码控制
    this.scroller.scrollPage({
      next:true // 下一页
      next:false // 上一页
    })
    
    练一练:

​ 答案:

 
@Entry
@Component
struct Index {
  nums:number[]=Array.from({length:200})
  scroller:Scroller=new Scroller()
  build() {
    Column(){
      Grid(this.scroller){
        ForEach(this.nums,(item:number,index:number)=>{
          GridItem(){
            Text((index+1).toString())
          }
          .backgroundColor('#0094ff')
          .width("25%")
        })
      }
      .padding(10)
      .rowsTemplate('1fr 1fr 1fr 1fr')
      .rowsGap(10)
      .columnsGap(10)
      .height(450)
      Row(){
        Button('上一页')
          .width(100)
          .onClick(()=>{
            this.scroller.scrollPage({
              next:false
            })
          })
        Button('下一页')
          .width(100)
          .onClick(()=>{
            this.scroller.scrollPage({
              next:true
            })
          })
      }
      .width("100%")
      .justifyContent(FlexAlign.SpaceAround)
    }
    .width("100%")
    .height("100%")
  }
}

自定义滚动条

使用属性调整

  1. scrollBar 设置滚动条状态

    BarState.off 关闭

    BarState.on 常驻

    BarState.auto 按需显示

  2. scrollBarColor 设置滚动条的颜色

.scrollBarWidth(20) // 宽度 .scrollBarColor(Color.Orange) // 滚颜色
.scrollBar(BarState.Off) // 关闭

自定义组件

主要就是三个参数如下:

  1. scroller 可控制组建的控制器

  2. direction:ScrollBarDirection.Vertical/Horizontal 滚动条的方向

  3. state 滚动条的状态

// 和 Grid 共用同一个 Scroller
scroller: Scroller = new Scroller()

// 和 Grid 共用同一个 Scroller
Grid(this.scroller){
  // 略
}

// 和 Grid 共用同一个 Scroller
// 创建 ScrollBar 组件并设置属性
ScrollBar({
  scroller: this.scroller,
  direction: ScrollBarDirection.Horizontal // 方向
}) {
  // 滚动内容 设置外观即可
  Text()
}
// 设置外观


最后

小编在之前的鸿蒙系统扫盲中,有很多朋友给我留言,不同的角度的问了一些问题,我明显感觉到一点,那就是许多人参与鸿蒙开发,但是又不知道从哪里下手,因为体系杂乱无章,教授的人也多,无从选择。有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)文档用来跟着学习是非常有必要的。 

为了确保高效学习,建议规划清晰的学习路线,涵盖以下关键阶段:

希望这一份鸿蒙学习文档能够给大家带来帮助~

GitCode - 全球开发者的开源社区,开源代码托管平台


 鸿蒙(HarmonyOS NEXT)最新学习路线

该路线图包含基础技能、就业必备技能、多媒体技术、六大电商APP、进阶高级技能、实战就业级设备开发,不仅补充了华为官网未涉及的解决方案

路线图适合人群:

IT开发人员:想要拓展职业边界
零基础小白:鸿蒙爱好者,希望从0到1学习,增加一项技能。
技术提升/进阶跳槽:发展瓶颈期,提升职场竞争力,快速掌握鸿蒙技术

2.视频教程+学习PDF文档

(鸿蒙语法ArkTS、TypeScript、ArkUI教程……)

 纯血版鸿蒙全套学习文档(面试、文档、全套视频等)

                   

鸿蒙APP开发必备

​​

总结

参与鸿蒙开发,你要先认清适合你的方向,如果是想从事鸿蒙应用开发方向的话,可以参考本文的学习路径,简单来说就是:为了确保高效学习,建议规划清晰的学习路线

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2116735.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Google Play结算防掉单方案

我们公司的产品主要是出海产品,使用的是Google Play支付,但是在上线以后,经常有客诉,说支付以后,权益没有到账,于是对整个Google支付体系做了研究了一下。 我们的整个支付流程图大概如下: 其中后端参考的文档地址为: https://developers.google.com/android-publishe…

Springboot中基于X509完成SSL检验的原理与实践

前言 各位对HTTPS不陌生吧?几乎涉及安全的领域,均要求通过HTTPS协议进行数据传输。而在传输过程中,又涉及到了SSL证书的使用。既然提到了SSL证书,那咱们先了解了解什么是SSL证书: SSL证书通过在客户端浏览器和Web服务…

生信代码入门:从零开始掌握生物信息学编程技能

少走弯路,高效分析;了解生信云,访问 【生信圆桌x生信专用云服务器】 : www.tebteb.cc 介绍 生物信息学是一个高度跨学科的领域,结合了生物学、计算机科学和统计学。随着高通量测序技术的发展,海量的生物数据需要通过编程来进行处理和分析。因此&#x…

如何使用云服务器AutoDL进行炼丹

如何使用云服务器进行炼丹 文章目录 如何使用云服务器进行炼丹1、选择平台2、学生认证3、租用新实例1)创建实例2)选择镜像3)注意事项 4、文件传输1)下载XFTP,用来传输文件2)XFTP连接 5、pycharm远程连接1&a…

【Github项目推荐】DataLoom

项目推荐 - DataLoom 项目背景 在数据驱动的时代,越来越多的企业和个人用户需要从复杂的数据中提取出高价值的信息。然而,传统的数据处理和分析流程复杂且耗时,需要技术人员的深度参与。那么,有没有一种工具能够简化这一过程&am…

Linux:归档及压缩

tar命令 • tar 集成备份工具 – -c:创建归档 – -x:释放归档 – -f:指定归档文件名称,必须在所有选项的最后 – -z、-j、-J:调用 .gz、.bz2、.xz 格式工具进行处理 – -t:显示归档中的文件清单 – -C:指定…

十年多空局

我收到的有关大洋彼岸的推送: 微信和头条上的长者们, 讲着他们小时候没有的GPU和生物技术, 看多 B站上的年轻人, 谈着他们一知半解的制度设计和宏观经济, 看空 十年尺度的看空与看多

githup怎么上传自己的项目

(1)首先进入自己要上传项目的文件夹中,然后点击Open git Bash here. (2)然后进入下面界面,输入git init (3)然后就会生成一个.git的文件夹 (4)输入git add *…

如何处理软件卸载不干净的情况?

如何处理软件卸载不干净的情况? 一、清理注册表 下载CCleaner,下载之后,点击settings,将语言改为中文。 点击注册表,点击扫描问题-修复选定的问题,最好将之前的注册表完整备份。 反复这一过程&#xff0c…

Spring Boot集成Tess4J实现OCR

1.什么是Tess4j? Tesseract是一个开源的光学字符识别(OCR)引擎,它可以将图像中的文字转换为计算机可读的文本。支持多种语言和书面语言,并且可以在命令行中执行。它是一个流行的开源OCR工具,可以在许多不同…

PHP-FPM 远程代码执行漏洞(CVE-2019-11043)复现

启动容器 docker-compose up -d 查看端口 docker ps 端口为:8080,访问网站,搭建成功 安装漏洞利用工具 攻击 go run . "http://172.16.1.14:8080//index.php" 显示漏洞利用成功,浏览器进行访问,成功复现

微信小程序开发项目详细讲解

​ 大家好,我是程序员小羊! 前言: 微信小程序是一种无需下载安装即可使用的应用程序,基于微信平台开发,能够提供类似原生应用的体验。以下是微信小程序开发的详细讲解,涵盖从项目准备、开发环境搭建到关键…

【无标题】符文价值的退化页

我们利用现有的符文体系建立了一个健全的符文扩展空间,可假若符文让我们感到十分困惑,我们不介意毁灭它们,让一切回到没有字迹的蛮荒纪。 如此,眼睛也失去了作用。我们的成GUO也会给后来者提供又是一DUI 令人眼花缭乱的无用符咒。…

DIC技术助力新能源汽车主机厂力学测试研发与整车性能提升

在新能源汽车研发过程中,非接触式全视场应变DIC测量方案,越来越受到汽车主机厂的信赖与认可。传统接触式传感器,在精度、灵活性和数据处理能力上存在局限。DIC技术可提供精确、高效、全视场、便捷的非接触式测量解决方案。 在汽车研发阶段&a…

OPCUA-PLC

下载opcua服务器(有PLC可以直连),UaAnsiCServer下载路径 双击运行如下,Endpoint显示opcua服务路径 opc.tcp://DESKTOP-9SD7K4B:48020 下载opcua客户端(类似编写代码连接操作),UaExpert下载路径 如果连接失败,有一个授权认证,点击同意就行 java代码实现连接opcUA操作 pom.…

Qt-QWidget的cursor属性(17)

目录 描述 相关API 使用 内置样式 使用ui界面操作 使用代码操作 自定义样式 热点修改 图片缩放 阿里巴巴矢量图 描述 这个是用来设置你的光标的样式的,具体来说是设置你程序内的光标样式,不是设置你系统的,当然我们也可以设置系统…

Java并发:互斥锁,读写锁,Condition,StampedLock

3,Lock与Condition 3.1,互斥锁 3.1.1,可重入锁 锁的可重入性(Reentrant Locking)是指在同一个线程中,已经获取锁的线程可以再次获取该锁而不会导致死锁。这种特性允许线程在持有锁的情况下,可…

JavaSE——封装、继承和多态

1. 封装 1.1 概念 面向对象程序三大特性:封装、继承、多态 。而类和对象阶段,主要研究的就是封装特性。何为封装呢?简单来说就是套壳屏蔽细节 。 比如:对于电脑这样一个复杂的设备,提供给用户的就只是:开…

嵌入式开发与应用实验三——定时器实现一秒闪烁一次

一、实验目的 1. 掌握使用 STM32 的通用定时器 TIM6/7实现 1s 定时的方法; 2. 掌握 STM32 的定时器的原理及基本功能; 3. 掌握定时器的基本配置功能。 二、实验内容 编程实现,利用定时器TIM6/7定时1秒,每隔1秒控制PBO端口 LED…

动态加载类对象

目录 框架时序图类图 ros中提供了动态加载class的方式。这样可以做到应用代码和class所在的so解耦合。一般情况下,使用dlopen动态加载C风格函数,C风格的类无法直接使用dlopen加载,通过ros中的这种方式,可以做到动态加载。 其思想核…