又到了午休吃饭的时候啦,趁着大家睡觉的时间赶紧努力写个博客吧!今天和大家分享一个比较简单的自定义列表界面。由于每天学习的时间是有限的,所以封装的组件名称是自己瞎写的,里边字段名称也没好好起一下,不过重在研究。后续会持续分享鸿蒙学习,感兴趣的可以一起交流,加个关注。demo下载链接
1. 实现的代码
@ComponentV2
export default struct CustomNavgation {
private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
private imgArr: string[] = ["a","b","c","d","e","f","touxiang","ic_start_icon","icon","banner_pic0"];
private positiveMessages: string[] = [
"每一天都是新的起点。",
"快乐是选择,不是条件。",
"你的努力会带来改变。",
"相信自己,你比想象中强大。",
"小进步,大成就。",
"积极的态度决定一切。",
"追梦路上,每一步都算数。",
"不怕路长,只怕志短。",
"每个早晨,都是对生活的重新开始。",
"今天会更好,因为有你在。"
];
@Local searchKeyword: string = '';///存储关键字
@Builder NavigationTitle() {
Column() {
Text('发现')
.fontColor('#182431')
.fontSize(30)
.lineHeight(41)
.fontWeight(700)
.margin({left: 10})
Text('永远要用心去发现世界的美!')
.fontColor('#182431')
.fontSize(14)
.lineHeight(19)
.opacity(0.4)
.margin({left: 10, top: 2, bottom: 20 })
}.alignItems(HorizontalAlign.Start)
}
@Builder NavigationMenus() {
Row() {
Image($r("app.media.touxiang"))
.width(24)
.height(24)
Image($r("app.media.startIcon"))
.width(24)
.height(24)
.margin({ left: 24 })
Image($r("app.media.ic_start_icon"))
.width(24)
.height(24)
.margin({ left: 24 })
}
}
@Computed get filteredItems() {
console.log('filteredItems called with searchIndex:', this.searchKeyword); // 调试输出
if (!this.searchKeyword) {
return this.arr; // 如果没有输入索引值,显示全部12条数据
}
const index = parseInt(this.searchKeyword, 10);
if (isNaN(index) || index < 0 || index >= this.arr.length) {
return []; // 输入无效索引值时,不显示任何数据
}
return [this.arr[index]]; // 根据输入的索引值筛选数据
}
getRandomMessage() {
const randomIndex = Math.floor(Math.random() * this.positiveMessages.length);
return this.positiveMessages[randomIndex];
}
build() {
Column() {
Navigation() {
TextInput({ placeholder: 'search...' })
.width('90%')
.height(40)
.backgroundColor('#FFFFFF')
.margin({ top: 8 })
.onChange((value: string) => {
this.searchKeyword = value
})
List({ space: 12, initialIndex: 0 }) {
ForEach(this.filteredItems, (item: number) => {
ListItem() {
Row(){
Text((item + 1).toString())
.margin({left : 15 })
.width('%40')
.height(72)
.fontSize(20)
.fontColor('black')
.fontWeight(500)
.textAlign(TextAlign.Start)
Image($r(`app.media.${this.imgArr[item]}`))
.width(56)
.height(56)
.margin({ left: 20 })
.borderRadius(5)
// 添加正面消息
Text(this.getRandomMessage())
.fontSize(14)
.fontColor('blue')
.margin({ left: 20 })
}
.width('90%')
.height(86)
.backgroundColor('#FFFFFF')
.borderRadius(24)
}
}, (item: number) => item.toString())
}
.height('90%')
.width('100%')
.margin({ top: 12, left: '10%' })
}
.title(this.NavigationTitle)
.menus(this.NavigationMenus)
.titleMode(NavigationTitleMode.Full)
.hideTitleBar(false)
.hideToolBar(false)
.onTitleModeChange((titleModel: NavigationTitleMode) => {
console.info('titleMode' + titleModel)
})
}.width('100%').height('100%').backgroundColor('#F1F3F5')
}
}
2. 代码解释说明
- @ComponentV2:这是一个装饰器,用于声明
CustomNavigation()是一个组件。 - export default struct CustomNavigation:这行代码定义了一个名为
CustomNavigation的默认导出组件。 - 这里的
struct指在该框架中用于定义组件的一种方式。 - build() 方法:这是组件的主要构建方法,在这里定义了组件的UI布局。
(1)、参数说明
-
arr: 一个数字数组,包含0到9共10个元素。
-
imgArr: 一个字符串数组,包含了一些图片资源的名字。
-
positiveMessages: 一个字符串数组,包含了一些正面鼓励的消息,用于在列表项中随机显示。
-
@Local searchKeyword: 一个本地变量,用于存储用户在搜索框中输入的关键字。
-
@Computed get filteredItems(): 这是一个计算属性,根据
searchKeyword的值来过滤arr数组中的项目。如果没有输入关键字,则显示所有项目;如果输入了有效的数字索引,则只显示对应的项目;如果是无效的索引值,则不显示任何项目。
(2)、 构建方法
- NavigationTitle() 和 NavigationMenus():这两个方法分别用于构建导航栏的标题和菜单部分。它们使用了
Column和Row布局来组织文本和图片元素。 - getRandomMessage():这个方法从
positiveMessages数组中随机选取一条消息返回,用于在列表项中显示。
(3)、主体布局
- TextInput:定义了一个搜索输入框,当用户输入时,会触发
onChange事件更新searchKeyword的值,从而影响filteredItems的计算结果。 - List:定义了一个列表,使用
ForEach循环遍历filteredItems,为每个项目创建一个ListItem。 - ListItem:每个列表项都包含了编号、图片和一条随机的正面消息。
- Navigation:定义了整个页面的导航部分,包括标题、菜单、标题模式等。
(4)、样式与布局
- 使用了多种样式属性如
fontColor、fontSize、margin等来定制组件的外观。 - 布局方面,通过
Column和Row来组织子元素,确保了良好的视觉效果。