一、实现需求
1、项目任务
通过进入首页,点击首页的按钮可以跳转到“今日买菜列表”项目列表中,列表里面呈现所需要购买的菜品,每一个项目上面都由一个空白框图标和文字组成。分别选中各个项目,可以实现空白框被勾选、文字增加删除线、斜体、透明度变低的效果,再次点击可以恢复到原来未被选中的状态。且添加返回按钮,实现返回首页。
2、目录结构
本项目总共需要创建2个页面文件、封装3个模块文件。
二、实现步骤
1、跳转和基础属性
(1)router进行首页的路由跳转和“今日买菜列表”页面的路由返回;
(2)设置首页的基本属性和点击事件,点击事件传递的参数除了路由地址,还有APP的名称。
//项目首页:引导页面
//需要进行页面跳转,实现跳转到其他功能页
//导入路由函数所在的库
import router from '@ohos.router';
//导入封装好的常量数据模型
import Constants from '../common/Constant'
@Entry
@Component
struct Index {
@State message: string = '今日买菜列表'
build() {
Row() {
Column() {
Button(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
//创建点击事件:实现页面跳转到功能页
.onClick(()=>{
router.pushUrl({
url:"pages/Tobuylist",
params:{
appName: 'ToBuyList 2.0'
}
})
})
}
.width('100%')
}
.height('100%')
//调用常量数据模型,设置背景颜色
.backgroundColor(Constants.BACKGROUND)
}
}
2、项目列表的创建
在ets目录下创建一个新的目录用于存放项目列表模块文件,并在该目录下创建一个新的项目列表文件,创建位置如下图所示:
3、列表结构搭建
该列表要实现的就是一个图标加文字,也就是调用Image组件和Text组件,共同放置在一个Row组件当中:
4、封装基本样式函数
Item_ImgSty()和Item_RowSty() 是自定义样式函数,分别为了适应图片样式和项目结构样式:
//声明选中框(图片)的样式函数
@Extend(Image) function Item_ImgSty(){
.width(30)
.height(30)
.objectFit(ImageFit.Contain) //图片平铺
.margin(15)
}
//Row样式函数
@Extend(Row) function Item_RowSty() {
.width('90%')
.height(55)
.backgroundColor(Color.White)
.borderRadius(30) //增加圆角边框
}
5、实现点击选中和取消选中的效果
首先需要创建是否选中的布尔类型状态变量,并且用@State装饰器修饰:@State isChoose: boolean = false //默认未选中
然后创建点击事件,若选中每一个项目,则将其勾选:
并且需要实现上图中的效果,通过判断该布尔值来设定来设定图标的变化,文字下划线、斜体、透明度的变化:
Row({space : 5}){
//根据是否选中,来确认使用哪个图标(选中和未选中)
if(this.isChoose){
//如果选中
Image($r('app.media.Choosing'))
.Item_ImgSty()
}else{
//如果未选中
Image($r('app.media.Choosing_not'))
.Item_ImgSty()
}
//因为只有选中和未选中两种情况,因此可以使用三元运算符进行简单的判断显示哪种文字效果(选中和未选中)
//如果选中,则添加一个下划线、斜体、透明度为0.5,如果未选中则无效果
Text(this.content)
.fontSize(25)
.decoration({type: this.isChoose ? TextDecorationType.LineThrough : TextDecorationType.None})
.fontStyle(this.isChoose ? FontStyle.Italic : FontStyle.Normal)
.opacity(this.isChoose ? 0.5 : 1)
}
.Item_RowSty()
//给Row组件创建点击事件
.onClick(()=>{
this.isChoose = !this.isChoose //点击一下选中,再点击一下取消选中
})
6、封装数据模块
同样需要创建一个新的目录存放该数据模型,再里面创建一个ArkTS文件,写入数据类,创建类的对象,并暴露类的对象。而且还需要提供一个非私有化的方法来暴露(提供)数据:
//创建一个存放模块数据的类
//并且需要暴露这个类,才能在外部进行调用
export class DataModule{
private Tasks: Array<string> = [
'主食材:西红柿和鸡蛋',
'副食材:大蒜和小葱',
'调料:盐、醋和鸡精',
'容器:7英寸陶瓷盘'
]
//提供一个非私有化的方法来暴露(提供)数据
getData(){
return this.Tasks //返回整个数组
}
}
//创建数据模块的对象
//并且需要暴露这个默认的对象
export default new DataModule()
7、封装常量模块
该常量模型专门用来存放属性等基本不会发生变化的数据,例如背景颜色、图标颜色、图标大小或其他枚举值,这样就可以使应用在整个项目中的元素统一化管理:
//封装常量文件:专门用来存放属性等基本不会发生变化的数据
//并且暴露这个类
export default class Constant{
//常量数据一般使用静态、只读数据(两个关键字都要有),需要加上变量注释并且命名尽量使用大写
//多个页面公用的背景颜色
static readonly BACKGROUND: string = '#eeb'
//这样就可以实现多个页面同步进行颜色(或其他常量属性)的修改
}
//常量不需要导出或者新建对象,可以直接调用;但是类需要被暴露
//new Constant()
8、列表结构和内容的融合实现
这就是待买列表的整体结构实现:
(1)接收从首页传递过来的数据
(2)导入自定义列表项目的子模块,并应用
(3)导入封装好的数据模块,并应用
(4)导入封装好的常量数据模块,并应用
(5)创建路由返回按钮
(6)设置全景颜色
//接收从首页传递过来的数据
import router from '@ohos.router';
let appName = router.getParams()['appName']
//导入自定义列表项目的子模块
import Tobuyitems from '../view/Tobuyitem'
//导入封装好的数据模块
import DataModules from '../viewData/DataModule'
//导入封装好的常量数据模块
import Constants from '../common/Constant'
@Entry
@Component
struct Tobuylist {
@State message: string = appName
//创建数组容器,方便后方进行遍历调用
private Tasks: string[] = []
//当组件加载完成,build之前再加载数据
aboutToAppear(){
//赋值数组容器,方便后方进行遍历调用
//从数据模型获取数据:使用封装的getData()方法
this.Tasks = DataModules.getData()
}
build() {
Row() {
Column({space : 25}) {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
//调用开头已经导入的自定义组件
Divider()
ForEach(this.Tasks, (item)=>{
Tobuyitems({content : item}) //将任务传递给Item模块
},(item)=>{
return item
//只能返回字符串,若为数组需要返回数组中的字符串元素;
//若为数值需要转为字符串,使用Json.stringify(item)
})
//若形参只有一个可以省略小括号,写成
// item => {
// return item
// })
//创建路由返回按钮
Divider()
Button('返回首页')
//创建点击事件
.onClick(()=>{
router.back()
})
}
.width('100%')
}
.height('100%')
//设置背景颜色:从外部数据模型Constants导入常量数据BACKGROUND
.backgroundColor(Constants.BACKGROUND)
}
}
三、实现效果
文章思路参考:最新最细鸿蒙HarmonyOS4.0教程(帝心+庄生)