HarmonyOS --- 首页(新新新手版,高手误入)
一、前言
每一个App都应该有一个首页,在Android中一般由MainActivity + Navigation + Fragment * N (随便你怎么组合,用别的也一样),鸿蒙呢?瞅瞅吧。阿弥陀佛,苦逼Android学完Java学Dart、学完Dart学Kotlin、学完Kotlin学Compose、学完Compose,HarmonyOS来啦!艹(更别说还有Framework)艹艹艹。
如果您有任何疑问、对文章写的不满意、发现错误或者有更好的方法,欢迎在评论、私信或邮件中提出,非常感谢您的支持。🙏
二、准备
因为众所不周知的原因,用的是编译SDK是9。DEV版本是DevEco Studio 4.0 Release。以及我只简单的写了一下底部的Tab,具体的内容也只有一个Text作为填充物~~~ 主要还是分享给大家如何写一个首页的基本代码啦~。

三、你需要一个项目
我们使用最最最基本的项目结构就好了,你可能需要如此做
File->New->Create Project->Application->Empty Ability->Next->(API 9)->Done->Finish 完事。
四、准备一点数据
显然,一个首页会有一个底部导航栏。一般而言会是“文字+图片”的组合,并且都具有选中状态、非选中状态。再显然这玩意是个数组。我们准备下
-
新建一个
data/MainCategory.ets文件记得新建一个
data文件夹简单的在里面定义一个数据结构
// 定义一个接口来表示项目类别的结构。export interface ItemCategory {// 当类别被选中时显示的图像资源。// 图像文件的引用selectedImage: Resource,// 未被选中时显示的图像资源。// 用于在用户界面上区分选中和未选中的状态。unselectedImage: Resource,// 类别的标题资源。// 一个字符串资源的引用title: Resource}
贴心的加上注释。PS:export表示某个实体(比如一个类、接口、变量或函数)应该被导出,使得它可以在其他文件或模块中被导入和使用。
-
构造一丢丢数据
我们打算做四个页面,所以准备四个数据吧~
export const MAIN_CATEGORIES: ItemCategory[] =[{selectedImage: $r('app.media.icon_home_select'),unselectedImage: $r('app.media.icon_home_unselect'),title: $r("app.string.main_home")},{selectedImage: $r('app.media.icon_group_select'),unselectedImage: $r('app.media.icon_group_unselect'),title: $r("app.string.main_group")},{selectedImage: $r('app.media.icon_message_select'),unselectedImage: $r('app.media.icon_message_unselect'),title: $r("app.string.main_message")},{selectedImage: $r('app.media.icon_mine_select'),unselectedImage: $r('app.media.icon_mine_unselect'),title: $r("app.string.main_mine")}]
PS:const关键字用于声明一个常量,意味着一旦被赋值后,其值就不能被改变(PPS:如果变量引用的是一个对象或数组,那么对象的属性或数组的元素是可以被修改)。
- 温柔的导入
回到我们的Index.ets。让我们导入刚刚准备的数据~
import { ItemCategory, MAIN_CATEGORIES } from './data/MainCategory'
import就是导入的意思,这玩意一般在文件的最前面。
{}用来声明你要导入这个文件中的什么(PS:这玩意能换名字)
import { ItemCategory, MAIN_CATEGORIES as NewName} from './data/MainCategory'
from 显然没什么用
./聪明的你,很清楚的知道这玩意的意思是:表示当前文件所在目录。顺带还想到了../表示:父目录。那还有......../?抱歉,没有了。但是你可以这么写
import { ItemCategory, MAIN_CATEGORIES as NewName} from '../../main/ets/data/MainCategory'
这样你就可以无限套娃了~一直../下去吧!少年!
五、准备好Tab
首先,肯定有当前展示页面之分,所以我们需要记录下选中的页面的Tab的Index
@State tabCurrentIndex: number = 0
PS:@State装饰的状态变量,一旦变量拥有了状态属性,就和自定义组件的渲染绑定起来。当状态改变时,UI会发生对应的渲染改变(官网抄的)。
我们直接使用鸿蒙之超能Tab之Tab,
import { ItemCategory, MAIN_CATEGORIES } from './data/MainCategory'/*生成的别管*/@Entry/*生成的别管*/@Component/*struct 生成的别管*/struct Index {@State tabCurrentIndex: number = 0/*build UI都写在这*/build() {// 创建 Tabs 组件,设置其属性Tabs({ barPosition: BarPosition.End }) {// ForEach 用于遍历 MAIN_CATEGORIES,为每个元素创建 TabContent 组件ForEach(MAIN_CATEGORIES, (item: ItemCategory, index: number) => {// 创建 TabContent 组件TabContent() {// 在这里可以添加 TabContent 组件的内容}// 设置 TabContent 组件的 tabBar 属性.tabBar(/* 这里可以设置 tabBar 相关属性 */)})}// 设置 Tabs 组件的其他属性.scrollable(false) // 设置是否可滚动 (首页一般来说,左右不能滑动吧?).barHeight(56) // 设置选项卡高度.barWidth('100%') // 设置选项卡宽度.vertical(false) // 设置选项卡排列方式(垂直或水平).backgroundColor(0xFFFEFEFE) // 设置背景色// 设置当选项卡改变时的回调函数.onChange((index: number) => {this.tabCurrentIndex = index; // 更新当前选中的选项卡索引})}}
可以看到,我们的Tab已经准备好了!然后我们需要填充下TabBar。
// 使用 @Builder 装饰器,表示 TabBarBuilder 是一个构建器方法@BuilderTabBarBuilder(index: number, selectedImage: Resource, unselectedImage: Resource, tabBarName: Resource) {// 构建一个列布局(Column),用于垂直排列子组件Column() {// 在列中添加一个图像组件// 如果当前索引与传入的索引相同,则显示选中的图像,否则显示未选中的图像Image(this.tabCurrentIndex === index ? selectedImage : unselectedImage).width(24) // 设置图像宽度.height(24) // 设置图像高度.margin({ bottom: 4 }) // 设置底部外边距// 在列中添加一个文本组件,用于显示选项卡名称Text(tabBarName).fontSize(10) // 设置字体大小.fontFamily('HarmonyHeiTi-Medium') // 设置字体.fontColor(this.tabCurrentIndex === index ? 0xFF2E2F2E : 0xFF848683) // 设置字体颜色,根据选中状态改变}// 设置列组件的宽度为 100%.width('100%')// 设置列组件的内边距.padding({ top: 6, bottom: 6 })// 设置子项在水平方向上的对齐方式为居中.alignItems(HorizontalAlign.Center)// 设置组件的 ID,使用索引来确保唯一性.id(`tabBar${index}`)}
那么往Tab组件里面一塞
tabBar(this.TabBarBuilder(index, item.selectedImage, item.unselectedImage, item.title))
那么Tab就完成啦~~~
六、TabContent
重要的页面来了。
为了不让Index内太臃肿,我们直接!新建一个 MainPageContainer类,并塞入一个Text
@Componentexport struct MainPageContainer {private mTitle: Resource;build() {Column() {Text(this.mTitle) // 使用 mTitle 作为文本内容.fontSize(50) .width('100%').height('100%') .textAlign(TextAlign.Center) .fontColor(0xFF9FE748) }.height('100%').padding({ top: 12 })}}
然后我们直接在Index中导入一下
import { MainPageContainer } from './MainPageContainer'
再这么一用
TabContent() {MainPageContainer({ mTitle: item.title })}
完事~
最后效果放在最前面啦~
七、总结
这玩意挺简单了,但是这DevEco-Studio是我用过的最垃圾的工具了。真的烂。这代码提醒,这代码补全,不如不要,啥也提醒不了,就只会“Did you mean xxxx”、“ignore x x x x"。💩。
为了能让大家更好的学习鸿蒙 (Harmony OS) 开发技术,这边特意整理了《鸿蒙 (Harmony OS)开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05
《鸿蒙 (Harmony OS)开发学习手册》
入门必看:https://qr21.cn/FV7h05
- 应用开发导读(ArkTS)
- 应用开发导读(Java)

HarmonyOS 概念:https://qr21.cn/FV7h05
- 系统定义
- 技术架构
- 技术特性
- 系统安全

如何快速入门:https://qr21.cn/FV7h05
- 基本概念
- 构建第一个ArkTS应用
- 构建第一个JS应用
- ……

开发基础知识:https://qr21.cn/FV7h05
- 应用基础知识
- 配置文件
- 应用数据管理
- 应用安全管理
- 应用隐私保护
- 三方应用调用管控机制
- 资源分类与访问
- 学习ArkTS语言
- ……

基于ArkTS 开发:https://qr21.cn/FV7h05
- Ability开发
- UI开发
- 公共事件与通知
- 窗口管理
- 媒体
- 安全
- 网络与链接
- 电话服务
- 数据管理
- 后台任务(Background Task)管理
- 设备管理
- 设备使用信息统计
- DFX
- 国际化开发
- 折叠屏系列
- ……

相关文章:
HarmonyOS --- 首页(新新新手版,高手误入)
一、前言 每一个App都应该有一个首页,在Android中一般由MainActivity Navigation Fragment * N (随便你怎么组合,用别的也一样),鸿蒙呢?瞅瞅吧。阿弥陀佛,苦逼Android学完Java学Dart、学完Da…...
springboot升级到3.2导致mybatis-plus启动报错
在springboot升级到3.2时,服务启动报错 java.lang.IllegalArgumentException: Invalid value type for attribute ‘factoryBeanObjectType’: java.lang.String: java.lang.IllegalArgumentException: Invalid value type for attribute factoryBeanOb…...
浏览器原理篇—渲染原理
目录导航 为什么要学习浏览器的渲染原理浏览器的渲染流程浏览器的渲染阻塞浏览器的渲染优化 为什么要学习浏览器的渲染原理? 知识深度挖掘: 帮助更好地理解前端性能优化。从而对实现效果进行针对性优化。如:**回流和重绘 **渲染机制。帮助…...
idea安装
mac安装路径 /Users/xxx/Library/Application Support/JetBrains/IntelliJIdeaxxx版本 将路径内文件直接复制到新版本即可, 注意如果为破解版idea.vmoptions配置中的内容是否添加或删除 maven配置如果使用idea, 需要在应用程序IntelliJ IDEA.app中显示包内容, /Applications/I…...
用Flask搭建简单的web模型部署服务
目录结构如下: 分类模型web部署 classification.py import os import cv2 import numpy as np import onnxruntime from flask import Flask, render_template, request, jsonifyapp Flask(__name__)onnx_session onnxruntime.InferenceSession("mobilen…...
PCL 点云匹配 3 之 (非线性迭代点云匹配)lM-ICP
一、IM迭代法 PCL IterativeClosestPointNonLinear 非线性L-M迭代法-CSDN博客 Matlab 非线性迭代法(3)阻尼牛顿法 L-M-CSDN博客 MATLAB实现最小二乘法_matlab最小二乘法-CSDN博客...
【C语言】SCU安全项目2-BufBomb
目录 关键代码解读: getxs() getbuf() test() 核心思路 具体操作1 具体操作2 前段时间忙于强网杯、英语4级和一些其他支线,有点摸不清头绪了,特别是qwb只有一个输出,太过坐牢,决定这个安全项目做完后就继续投身…...
C++第一讲之初入C++
注:本文是对于学完C语言再学C同学的讲解,主要补充C与C语言不同之处,如果你没学过C语言,不建议观看本文。 一.C简介 我们都知道C语言是过程性语言(强调的是实现过程),即对计算机语言要处理的两…...
如何实现公网访问本地内网搭建的WBO白板远程协作办公【内网穿透】
最近,我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念,而且内容风趣幽默。我觉得它对大家可能会有所帮助,所以我在此分享。点击这里跳转到网站。 文章目录 前言1. 部署WBO白板2. 本地访问WBO白板3. Linux 安装cp…...
js知识点1:防抖节流
js知识点1:防抖节流 防抖节流 防抖节流,本质上是优化高频率执行代码的一种手段 定义: 防抖: n 秒后再执行该事件,若在 n 秒内被重复触发,则重新计时 节流: n 秒内只运行一次,若在 n 秒内重复触发࿰…...
虚拟机下Ubuntu上网设置
文章目录 一、虚拟机上网的两种方式1.1 NAT模式(Network Address Translation)1.2 桥接模式(Bridge Mode)1.3 简介 二、实际配置2.1 NAT模式配置2.2 桥接模式配置 之前跟着博客配了好几个也没用,后来自己慢慢模式实践测…...
Unity3d C#利用Editor编辑器拓展实现配置UI背景样式一键设置UI背景样式功能(含源码)
前言 在开发UI滚动列表的时候,经常会有每项的背景图不统一的情况,会间隔重复的情况居多。这种情况下,手动去设置间隔一行的背景图或者颜色是比较麻烦的。在此背景下,笔者尝试写个小工具,在搭建UI时配置一下循环背景的…...
【微服务】服务间调用
当我们的应用从一个大单体拆分成多个微服务之后,服务间调用有多少种方式?服务间调用如果出现超时,如果避免雪崩,即如何做限流熔断机制,原理是什么? 服务间调用方式 OpenFeign 使用Feign进行服务间调用,我们会在启动类加@EnableFeignClients启用。 package org.sprin…...
一句话分清C/C++声明和定义
定义告诉编译器在在哪个位置存储变量,声明没有 声明:告诉编译器,变量类型和名字 定义:告诉编译器变量存储的位置。 举例子 int i; // 这是声明定义。声明:告诉编译器变量类型int,变量名字i, // 定义&…...
《哥德尔证明》阅读笔记——初等命题逻辑的一致性证明过程
前言 前两节主要阐述了公理系统的发展历史,一致性问题的提出,以及希尔伯特的洞见,本节将给出哥德尔证明所需的最后一次具体背景阐述,包含两个问题:一是罗素所著的《数学原理》是为何而写?二是从数学原理中…...
迪文屏开发保姆级教程—弹出键盘录入ASCII字符
本篇文章主要介绍了在DGBUS平台上使用文本录入键盘录入ASCII字符,数字和字母的教程。 文本录入键盘支持录入ASCII字符,数字和字母。 官方开发指南PDF:(不方便下载的私聊我发给你) https://download.csdn.net/download…...
Java,处理字符串的案例()
场景 为了得到一个都是英雄名字的字符数组,需要对如下字符串进行处理 疾风剑豪,影流之主,封魔剑魂,暗裔剑魔,无极剑圣,无双剑姬,武器大师,德邦总管,蛮族之王࿰…...
微信小程序更新机制
1/同步更新 1、定期检查更新时; 2、长期未使用,首次进入会同步更新,但在弱网或者下载新版本失败的情况下,还会使用旧版本。 2/异步更新: 启动时异步更新 3/开发者手动触发更新 在启动时异步更新的情况下,…...
CentOS 7 部署 Nacos-2.3.0 (单机版)
CentOS 7 部署 Nacos-2.3.0 (单机版) 1. 下载 Nacos 安装包 历史版本:https://github.com/alibaba/nacos/releases/ 我选的是 2.3.0 版本,https://github.com/alibaba/nacos/releases/download/2.3.0/nacos-server-2.3.0.tar.g…...
Springboot优雅实现对接口返回统一封装
前端在调用后端接口时往往不同的接口返回的数据是不一样的,但是通常我们会与前端约定一个固定的返回格式,通过固定的格式告诉他们什么时候接口是返回成功,什么时候返回失败,返回成功后他们如何拿到接口返回的数据去渲染前端页面。…...
Display Driver Uninstaller深度清理实战指南
Display Driver Uninstaller深度清理实战指南 【免费下载链接】display-drivers-uninstaller Display Driver Uninstaller (DDU) a driver removal utility / cleaner utility 项目地址: https://gitcode.com/gh_mirrors/di/display-drivers-uninstaller 当你遭遇游戏帧…...
避开这些坑!群晖+acme.sh申请Let’s Encrypt证书的完整指南
群晖NAS上零踩坑申请Lets Encrypt证书的终极实践手册 每次看到浏览器地址栏那个刺眼的"不安全"提示就浑身难受?作为群晖深度用户,我花了三个周末时间踩遍了所有证书申请的坑。从idn指令缺失到nss验证失败,从API调用超时到证书自动更…...
OpenClaw性能调优:Qwen3-32B镜像的批处理与并发控制
OpenClaw性能调优:Qwen3-32B镜像的批处理与并发控制 1. 为什么需要性能调优 当我第一次在RTX4090D上部署Qwen3-32B模型并接入OpenClaw时,本以为24GB显存足以应对各种任务。但现实很快给了我一记重拳——当我尝试批量处理100个文档时,系统不…...
OpenClaw开发辅助:Qwen3.5-9B实现日志分析与错误自动修复
OpenClaw开发辅助:Qwen3.5-9B实现日志分析与错误自动修复 1. 为什么需要AI辅助日志分析? 每次凌晨被报警短信吵醒,盯着密密麻麻的日志文件找异常时,我都会想:如果能有个AI助手帮我自动分析日志、定位问题甚至尝试修复…...
深度解析Internet Archive下载器:数字图书馆资源获取的完整方案
深度解析Internet Archive下载器:数字图书馆资源获取的完整方案 【免费下载链接】internet_archive_downloader A chrome/firefox extension that download books from Internet Archive(archive.org) and HathiTrust Digital Library (hathitrust.org) 项目地址:…...
告别云端推理:手把手教你用Vivado HLS在AX7350开发板上部署YOLOv3(附完整工程)
从零部署YOLOv3到AX7350开发板:FPGA加速实战全流程解析 在边缘计算领域,FPGA因其低延迟、高能效和可重构特性,成为深度学习模型部署的热门选择。本文将带您完成YOLOv3目标检测模型在AX7350开发板上的完整部署流程,从环境准备到最终…...
Go 协程池设计与调度实现
Go 协程池设计与调度实现 在并发编程中,Go 语言的协程(goroutine)以其轻量级和高性能著称。无限制地创建协程可能导致资源耗尽,影响系统稳定性。为此,协程池的设计与调度成为优化高并发场景的重要手段。本文将深入探讨…...
用腾讯云轻量锐驰和对象存储,手把手教你30分钟搞定私人不限速网盘(附SSL证书配置)
零基础30分钟搭建高性能私人网盘:腾讯云轻量锐驰对象存储实战指南 你是否也受够了公有网盘动辄几百KB的下载速度?每次分享文件给朋友,对方总要忍受龟速下载的煎熬。更别提那些突然消失的文件和频繁弹出的会员广告——是时候拥有一个完全自主掌…...
OpenClaw硬件监控:nanobot定时报告系统资源使用情况
OpenClaw硬件监控:nanobot定时报告系统资源使用情况 1. 为什么需要自动化硬件监控 去年夏天,我的开发机因为内存泄漏问题突然宕机,导致一个重要的线上演示被迫推迟。当时我就意识到,手动检查系统资源的方式既不及时也不可靠。直…...
RAG的墓志铭:当AI不再需要检索
上个月读到一篇在 Hacker News 上引发热议的文章——《The RAG Obituary: Killed by Agents, Buried by Context Windows》。作者 Nicolas Bustamante 是金融科技公司 Fintool 的创始人,他在文中抛出了一个颇具争议的观点:RAG(检索增强生成&a…...
