HarmonyOs 应用基础--ArkTS-核心-基础

目录

八. ArkTS-语句-类型进阶与渲染控制

1. 对象进阶

1.1. 定义对象数组

1.2. 使用对象数组

2. 渲染控制 - ForEach

2.1. ForEach语法

 2.2. ForEach使用优化代码

 2.3. 案例-学生档案

实现思路

3. Math对象

 4. 综合案例 -- 抽奖卡案例

4.1. 初始页面布局(静态)

4.2. 根据数据渲染初始页面

4.2.1. 准备响应数据

4.2.2. 渲染初始页面

4.3. 遮罩层静态布局

4.4. 遮罩层动态交互

4.4.1. 按钮交互

4.4.2. 图片数据

4.5. 中奖结果

 4.5.1. 抽奖静态页面

4.5.2. 条件渲染-抽卡与抽奖页面

4.5.3. 抽奖数据处理

4.6. 再次抽奖


八. ArkTS-语句-类型进阶与渲染控制

今日核心

  1. 对象
  2. 渲染控制ForEach

1. 对象进阶

1.1. 定义对象数组

// 1. 定义接口
interface Person {stuId: numbername: stringgender: stringage: number
}// 2. 根据接口定义对象数组
let students: Person[] = [{stuId: 1, name: '小红', gender: '女', age: 18},{stuId: 2, name: '小明', gender: '男', age: 19},{stuId: 3, name: '大强', gender: '男', age: 18}
]

1.2. 使用对象数组

  • 访问某一个对象:
    • 每一对象在数组中都是有对应的下标的, 可以通过 数组名[下标] 访问
  • 访问某一对象的某一个属性
    • 先找到要访问的对象, 在该对象的属性访问属性 数组名[下标].属性名 访问
  • 依次访问每一个对象
    • for ... of 进行访问即可
// 3. 访问属性 数组名[下标].属性名
console.log('小红的年龄是', students[0].age)// 4. 遍历对象数组
for (const item of students) {console.log('学生姓名是', item.name)
}

2. 渲染控制 - ForEach

当我们页面中的区域中有多个样式相同的小区域,只有内容数据不一样的时候, 为了提升代码的复用率,不需要一个一个的编写UI组件,我们可以将所有的数据整合成一个数组, 并采取ForEach进行循环渲染.如下图区域,如果我们分别实现每个栏目,代码太过于冗余,这时就可以使用ForEach进行渲染了

2.1. ForEach语法

ForEach基于数组类型数据来进行循环渲染,需要与容器组件配合使用,且接口返回的组件应当是允许包含在ForEach父容器组件中的子组件。

  • 语法: ForEach(arr, (item, index) => {})

参数

参数类型

是否必须

参数说明

arr

Array

数据源, 根据该数组生成对应的UI组件渲染到页面中:

  • 可以为空数组

UI组件生成函数

(item: any, index?: number) => void

UI组件生成函数

  • 为数组中的每个元素创建对应的组件
  • item: 代表每一个数组元素, 类型与数组元素保持一致,不可以省略
  • index: 代表每一个数组元素的下标,可以省略

 2.2. ForEach使用优化代码


@Entry@Componentstruct Index {build() {Column(){Text('电子产品').fontSize('24').fontWeight(700).fontColor(Color.Orange).width('100%').padding(15)Text('精品服饰').fontSize('24').fontWeight(700).fontColor(Color.Orange).width('100%').padding(15)Text('母婴产品').fontSize('24').fontWeight(700).fontColor(Color.Orange).width('100%').padding(15)Text('影音娱乐').fontSize('24').fontWeight(700).fontColor(Color.Orange).width('100%').padding(15)Text('海外旅游').fontSize('24').fontWeight(700).fontColor(Color.Orange).width('100%').padding(15)}.width('100%').height('100%')}}

 完成代码

@Entry@Componentstruct Index {@Statetitles:string[] = ['电子产品', '精品服饰', '母婴产品', '影音娱乐', '海外旅游']build() {Column() {ForEach(this.titles, (item: string, index: number) => {Text(item).fontSize('24').fontWeight(700).fontColor(Color.Orange).width('100%').padding(15)})}}}

 2.3. 案例-学生档案

模版代码 

@Entry
@Component
struct Index {build() {Column() {Row() {Text(`姓名:张三,年龄:18`).fontSize(18).fontColor('#fff')Button('年龄+1').backgroundColor('#e64133')}.width('100%').height(60).backgroundColor(Color.Orange).borderRadius(5).padding({left: 10, right: 10}).margin({bottom: 10}).justifyContent(FlexAlign.SpaceBetween)}.padding(20)}
}
实现思路
  • 准备数据
    • 定义数组元素接口
    • 根据接口创建对象数组保存数据
  • ForEach循环渲染
    • 使用数组元素的属性(item.属性名)动态填充UI组件对应的位置
interface Person {stuId: numbername: stringgender: stringage: number
}@Entry
@Component
struct Index {@Statestudents: Person[] = [{stuId: 1, name: '小红', gender: '女', age: 18},{stuId: 2, name: '小明', gender: '男', age: 19},{stuId: 3, name: '大强', gender: '男', age: 18}]build() {Column() {ForEach(this.students, (item: Person, index: number) => {Row() {Text(`姓名:${item.name},年龄:${item.age}`).fontSize(18).fontColor('#fff')Button('年龄+1').backgroundColor('#e64133').onClick(() => {// item.age += 1this.students[index] = {stuId: item.stuId,name: item.name,gender: item.gender,age: item.age += 1}})}.width('100%').height(60).backgroundColor(Color.Orange).borderRadius(5).padding({left: 10, right: 10}).margin({bottom: 10}).justifyContent(FlexAlign.SpaceBetween)})}.padding(20)}
}

3. Math对象

Math 是一个内置对象,它拥有一些数学常数属性和数学函数方法, Math 用于 Number 类型数据的处理.

Math.random()

  • 随机数
  • 取值范围 [0, 1)之间的随机小数,左闭右开, 可以取到0,但是取不到1

Math.ceil()

  • 需要一个数字形参数
  • 总是向上取整

Math.floor()

  • 需要一个数字形参数
  • 总是向下取整
  • 代码测试
// 1. 随机数
console.log('Math对象', Math.random())  // 0-1 之间的随机小数// 2. 向上取整
console.log('Math对象', Math.ceil(1.1))  // 2
console.log('Math对象', Math.ceil(1.9))  // 2// 3. 向下取整
console.log('Math对象', Math.floor(1.1))  // 1
console.log('Math对象', Math.floor(1.9))  // 1
  • 求0--10之间的随机整数
// 0-10 之间的随机数
console.log('Math对象', Math.random() * 11)// 0-10 之间的随机 整数
console.log('Math对象', Math.floor(Math.random() * 11))

 4. 综合案例 -- 抽奖卡案例

实现如下图所示的效果 

4.1. 初始页面布局(静态)

备注:无数据

@Entry
@Component
struct Index {build() {Column() {// 一. 初始界面Column() {// 图片区域Flex({wrap: FlexWrap.Wrap}) {Badge({count: 1,style: {badgeSize: 16, badgeColor: '#f00', fontSize: 14}}) {Image($r('app.media.bg_00')).width(80)}.margin(15)Badge({count: 1,style: {badgeSize: 16, badgeColor: '#f00', fontSize: 14}}) {Image($r('app.media.bg_00')).width(80)}.margin(15)Badge({count: 1,style: {badgeSize: 16, badgeColor: '#f00', fontSize: 14}}) {Image($r('app.media.bg_00')).width(80)}.margin(15)Badge({count: 1,style: {badgeSize: 16, badgeColor: '#f00', fontSize: 14}}) {Image($r('app.media.bg_00')).width(80)}.margin(15)Badge({count: 1,style: {badgeSize: 16, badgeColor: '#f00', fontSize: 14}}) {Image($r('app.media.bg_00')).width(80)}.margin(15)Badge({count: 0,style: {badgeSize: 16, badgeColor: '#f00', fontSize: 14}}) {Image($r('app.media.bg_00')).width(80)}.margin(15)}.margin({top: 100, bottom: 50}).padding({left: 15})// 抽卡按钮Button('立即抽卡').width(200).backgroundColor('#ED5B8C').stateStyles({pressed: {.backgroundColor('#EA446C')}}).animation({duration: 1000})}}}
}

4.2. 根据数据渲染初始页面

4.2.1. 准备响应数据

思路: 观察效果可以发现列表区域的每一项, 至少需要两个数据:

  1. 图片的地址
  2. 抽中的数量
// 初始界面卡片接口
interface Card {url: stringnum: number
}// 初始界面卡片状态@Stateimages: Card[] = [{url: 'app.media.bg_00', num: 0},{url: 'app.media.bg_01', num: 0},{url: 'app.media.bg_02', num: 0},{url: 'app.media.bg_03', num: 0},{url: 'app.media.bg_04', num: 0},{url: 'app.media.bg_05', num: 0}]
4.2.2. 渲染初始页面

ForEach() 渲染 Badge组件

// 初始界面卡片接口
interface Card {url: stringnum: number
}@Entry
@Component
struct Index {// 初始界面卡片状态@Stateimages: Card[] = [{url: 'app.media.bg_00', num: 0},{url: 'app.media.bg_01', num: 0},{url: 'app.media.bg_02', num: 0},{url: 'app.media.bg_03', num: 0},{url: 'app.media.bg_04', num: 0},{url: 'app.media.bg_05', num: 0}]build() {Column() {// 一. 初始界面Column() {// 图片区域Flex({wrap: FlexWrap.Wrap}) {ForEach(this.images, (item: Card, index: number) => {Badge({count: item.num,style: {badgeSize: 16, badgeColor: '#f00', fontSize: 14}}) {Image($r(`${item.url}`)).width(80)}.margin(15)})}.margin({top: 100, bottom: 50}).padding({left: 15})// 抽卡按钮Button('立即抽卡').width(200).backgroundColor('#ED5B8C').stateStyles({pressed: {.backgroundColor('#EA446C')}}).animation({duration: 1000})}}}
}

4.3. 遮罩层静态布局

单击“立即抽卡”按钮后显示的遮罩层

  • 标签解构: Column > Text + Image + Button

样式枚举:

  1. 遮罩层整体样式:

宽度 -> 100% 高度 -> 100% 背景色 -> 'rgba(0,0,0,0.8)' 定位 内容主轴对齐方式 -> 居中

  1. 文字: 颜色 -> '#F5EBCF' 大小 -> 25 粗细 -> 600
  2. 图片: 外边距 -> 30 宽度 -> 200
  3. 按钮样式:

宽度 -> 200 高度 -> 50 背景色 -> 透明 边框 -> 粗细 2 颜色 '#FFF9E0'

Column({space: 30}) {Text('获取生肖卡').fontColor('#F5EBCF').fontSize(25).fontWeight(600)Image($r('app.media.img_00')).width(200)Button('开心收下').width(200).height(50).backgroundColor(Color.Transparent).border({width: 2, color: '#FFF9E0'})
}
.width('100%').height('100%').backgroundColor('rgba(0,0,0,0.8)').justifyContent(FlexAlign.Center).position({x: 0, y: 0})

4.4. 遮罩层动态交互

4.4.1. 按钮交互

遮罩层的显示隐藏, 图片添加缩放效果

思路分析:

默认状态

  1. 界面隐藏visibility(Visibility:Hidden)
  2. 生肖卡隐藏(缩放比例为0)

抽卡后状态

  1. 界面显示visibility(Visibility:Visible)
  2. 生肖卡显示(缩放比例为1)

单击“开心收下”按钮

  1. 界面隐藏
 // 是否显示生肖卡界面状态@StateisVisible: boolean = false// 生肖卡缩放状态@StateimgX: number = 0@StateimgY: number = 0// 抽卡按钮
Button('立即抽卡').width(200).backgroundColor('#ED5B8C').stateStyles({pressed: {.backgroundColor('#EA446C')}}).animation({duration: 1000}).onClick(() => {this.isVisible = truethis.imgX = 1this.imgY = 1})// 二. 生肖卡界面
Column({space: 30}) {Image($r('app.media.img_00')).width(200).scale({x: this.imgX, y: this.imgY}).animation({duration: 400})Button('开心收下').onClick(() => {// 生肖卡界面隐藏;卡片隐藏this.isVisible = falsethis.imgX = 0this.imgY = 0})
}// 使用状态控制整个界面显隐.visibility(this.isVisible ? Visibility.Visible : Visibility.Hidden)
4.4.2. 图片数据

随机抽中一张生肖卡,单击“开心收下”按钮,显示对应的生肖卡,角标+1

思路分析:

  1. 随机显示生肖卡
  2. 卡片数量 +1
// 随机生肖卡序号@StaterandomIndex: number = -1Button('立即抽卡').onClick(() => {// 随机生肖卡 0-5this.randomIndex = Math.floor(Math.random() * 6)})
Column({space: 30}) {// 使用生成的随机数筛选生肖卡Image($r(`app.media.img_0${this.randomIndex}`))Button('开心收下').onClick(() => {// 收下卡片更新对象数组 -- 替换初始界面图片url和角标数字this.images[this.randomIndex] = {url: `app.media.img_0${this.randomIndex}`,num: this.images[this.randomIndex].num += 1}})
}

4.5. 中奖结果

6张卡片数量均>=1,则可以抽奖一次(显示抽奖页面:奖品随机)

 4.5.1. 抽奖静态页面

// 抽奖页面-遮罩层
Column({space: 50}) {Text('恭喜获得手机一部').fontColor('#F5EBCF').fontSize(25).fontWeight(600)Image($r('app.media.hw')).width(300)Button('再来一次').width(200).height(50).backgroundColor(Color.Transparent).border({width: 2, color: '#FFF9E0'})
}
.width('100%').height('100%').backgroundColor('rgba(0,0,0,0.8)').justifyContent(FlexAlign.Center).position({x: 0, y: 0})
4.5.2. 条件渲染-抽卡与抽奖页面

集齐6种生肖卡显示抽奖页面,否则显示抽卡页面

// 是否中奖状态@StateisGet: boolean = false// 三. 抽奖中奖界面
if (this.isGet) {Column({space: 50}) {}
}
4.5.3. 抽奖数据处理

判断是否可以抽奖:定义count变量保存已经获得的卡片种类数量(如果每个生肖卡数量>=1,则count+1)

如果count == 6,说明已经得到了6种卡,则可以抽奖,渲染抽中的奖品图片

思路分析:

声明一个变量 保存 中奖的结果 、声明一个变量保存中奖的名称

  1. 声明一个变量保存 获得卡片的种类
  2. 遍历数组, 如果卡片的个数 大于 等于1 获得种类加 1 否则 肯定没有中奖 跳出循环
  3. 判断种类是否有 6 种
    1. 如果等于 6 说明已经集够卡片 中奖结果改为 true
    2. 罗列所有的奖品名称
    3. 获取随机下标 0 -- 2
    4. 获取随机名称
// 奖品状态@StatejiangPin: string = ''// 抽奖页面-遮罩层
Column({space: 50}) {Text('恭喜获得手机一部')Image($r(`app.media.${this.prize}`))Button('再来一次')
}Button('开心收下').onClick(() => {// 判断是否可以抽奖:定义count变量保存已经获得的卡片种类数量(如果每个生肖卡数量>=1,则count+1)// 如果count == 6,说明已经得到了6种卡,则可以抽奖// 判断是否中奖let count: number = 0for (const item of this.images) {if (item.num >= 1) {count += 1} else {break}}if (count == 6) {this.isGet = true}// 随机奖品const arr: string[] = ['hw', 'xm', 'pg']let randomNum: number = Math.floor(Math.random() * 3)this.jiangPin = arr[randomNum]})

4.6. 再次抽奖

单击“再来一次”按钮,重新抽卡

  1. 关闭遮罩层:中奖状态为 false
  2. 初始化列表数据
Button('再来一次').onClick(() => {this.isGet = falsethis.images = [{url: 'app.media.bg_00', num: 0},{url: 'app.media.bg_01', num: 0},{url: 'app.media.bg_02', num: 0},{url: 'app.media.bg_03', num: 0},{url: 'app.media.bg_04', num: 0},{url: 'app.media.bg_05', num: 0}]})

案例代码:【免费】HarmonyOs应用基础-ArkTS-核心-基础-抽奖案例代码资源-CSDN文库

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

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

相关文章

通信工程学习:什么是GSMP通用交换机管理协议

GSMP:通用交换机管理协议 GSMP(General Switch Management Protocol,通用交换机管理协议)是一种用于IP交换机对ATM交换机进行控制的协议。以下是对GSMP的详细解释: 一、定义与概述 GSMP是一种异步协议,它在…

【JavaSE】基础学习以及简单的计算器应用程序GUI实现

计算机中的二进制 在计算机中,二进制表示是指使用两种状态来表示数字、字符或其他数据。计算机只能处理0和1,因为它们可以通过物理设备的两种状态(如高电压或低电压)来表示。二进制数的每一位称为一个bit,而八位称为一…

在国产芯片上实现YOLOv5/v8图像AI识别-【4.4】RK3588网络摄像头推理后推流到RTSP更多内容见视频

本专栏主要是提供一种国产化图像识别的解决方案,专栏中实现了YOLOv5/v8在国产化芯片上的使用部署,并可以实现网页端实时查看。根据自己的具体需求可以直接产品化部署使用。 B站配套视频:https://www.bilibili.com/video/BV1or421T74f 前言…

React(v18)事件原理

1. 背景 在旧版 React 中,事件的处理方式不完全符合标准的事件流顺序。事件的处理顺序是: 事件监听(比如通过 addEventListener 注册的事件)捕获阶段的事件处理(即从父元素到子元素的处理)冒泡阶段的事件…

【论文阅读】01-Survey on Temporal Knowledge Graph

原文名称:Survey on Temporal Knowledge Graph 1 Introduction 目前有两种方法:基于距离模型的嵌入变换方法和基于语义匹配模型的双线性模型。它们的思想都是将包含实体和关系的知识图谱嵌入到连续的低纬度实向量空间中 时间知识图的推理有两种,第一种是…

斐纳切数列考试题

计算机二级考试有一道题 result [] a,b0,1 while a<100:print(a,end,) a, b b, ab # 0,1,1,2,3,5,8,13,21,34,55,89,

python爬虫代理ip池搭建

最近大量爬取数据的时候总会遇到被封ip的情况&#xff0c;所有打算自己搭建一个代理ip池来使用。本次使用的是开源的ip代理池项目ProxyPool 1.下载redis数据库 redis安装 这里我选择直接下载redis的解压包形式&#xff0c;方便安装。下载地址&#xff1a;发布 TPORADOWSKI/RED…

小型公司机房运维如何管理

本人从业五年&#xff0c;基本是中小型公司。经手的机房也基本是从0-1。今天浅谈一下如果管理小型公司的机房。 机房管理&#xff0c;一般分成以下几个方面&#xff1a; 1、环境管理&#xff1a;比如弱电、强点线路是否排列整齐&#xff1b;机柜门是否做到全部关闭&#xff1b…

SCAU算法竞赛入门指北

首先&#xff0c;还是欢迎各位小朋友来到华南农业大学&#xff0c;虽然不是什么ACM强校&#xff0c;但是姑且还是有这么个校队存在的。本文的主要目的是给各位OI✌️介绍下acm和oi的区别&#xff0c;给各位纯萌新介绍下你需要做什么&#xff0c;以及进校队的时间线。 ACM是什么…

UE4_后期处理_后期处理材质及后期处理体积二

效果&#xff1a; 步骤&#xff1a; 1、创建后期处理材质,并设置参数。 2、回到主界面&#xff0c;找到需要发光的物体的细节面板。 渲染自定义深度通道&#xff0c;默认自定义深度模具值为10&#xff08;需要修改此值&#xff0c;此值影响物体的亮度&#xff09;。 3、添加…

JVM系列(六) -对象的创建过程

一、摘要 在之前的文章中,我们介绍了类加载的过程和 JVM 内存布局相关的知识。本篇我们综合之前的知识,结合代码一起推演一下对象的真实创建过程,以及对象创建完成之后在 JVM 中是如何保存的。 二、对象的创建 在 Java 中,创建对象的方式有很多种,比如最常见的通过new …

Spring 循环依赖原理及解决方案

一、什么是循环依赖 循环依赖指的是一个实例或多个实例存在相互依赖的关系&#xff08;类之间循环嵌套引用&#xff09;。 举例&#xff1a; Component public class AService {// A中注入了BAutowiredprivate BService bService; }Component public class BService {// B中也…

Redis 的标准使用规范之数据类型使用规范

数据类型使用规范 提示&#xff1a;以下是本篇文章正文内容&#xff0c;可供参考 (1)、字符文本&#xff08;STRING&#xff09; 【建议】选型为简易文本类缓存 &#xff1a;比如普通的字符、文本、Json 结构 &#xff0c;通常能起到加速读写和降低后端压力的作用。 【建议】…

数据库系统 第46节 数据库版本控制

数据库版本控制是确保数据库架构和数据模型随着时间的推移而正确演进的重要实践。它允许开发团队跟踪数据库的变更历史&#xff0c;回滚到以前的版本&#xff0c;以及在不同环境&#xff08;如开发、测试和生产环境&#xff09;之间同步数据库结构。以下是两种主要的数据库版本…

ActiveMQ 的网络连接及消息回流机制

1、ActiveMQ 的网络连接 activeMQ 如果要实现扩展性和高可用性的要求的话&#xff0c;就需要用用到网络连接模式。 NetworkConnector&#xff1a;主要用来配置 broker 与 broker 之间的通信连接 如上图所示&#xff0c;MQ 服务器1 和MQ 服务器2 通过 NewworkConnector 相连&…

Leetcode Hot 100刷题记录 -Day12(轮转数组)

轮转数组 问题描述&#xff1a; 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4]解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向…

一台笔记本电脑的硬件都有哪些以及对应的功能

一台笔记本电脑的硬件通常包括多个关键组件&#xff0c;这些组件共同协作&#xff0c;确保电脑的正常运行。以下是笔记本电脑的主要硬件及其功能&#xff1a; 1. 中央处理器&#xff08;CPU&#xff09; 功能&#xff1a;CPU 是电脑的“大脑”&#xff0c;负责处理所有的计算…

CocosCreator面试真题详解

最近有位同学面试Cocos Creator&#xff0c;我们把面试时问道的真题列举出来&#xff0c;并配上参考答案。 问题1: 你们公司项目时如何做战斗系统的? 面试官你好&#xff0c;做战斗系统和架构的时候&#xff0c;我们一般把代码逻辑分成3层来设计&#xff0c;同时把数据独立出…

Linux业务系统将/home目录删除并将空间扩给根目录

原有目录空间分配如下&#xff1a; [roothisdb ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/cl-root 21G 10G 11G 50% / devtmpfs 905M 0 905M 0% /dev tmpfs 920M 177M 744M 20% /dev/shm tm…

千益畅行,共享旅游卡,有哪些优势和特点?

1、同行人数灵活&#xff1a; 与一般旅游卡相比&#xff0c;千益畅行旅游卡对同行人数的限制更宽松&#xff0c;单卡支持 2 至 6 人同时出行&#xff0c;能满足小团体、家庭等多人出行需求&#xff0c;为多人共同出游提供了便利和优惠。 2、服务模式多样&#xff1a; 1&#xf…