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优雅实现对接口返回统一封装
前端在调用后端接口时往往不同的接口返回的数据是不一样的,但是通常我们会与前端约定一个固定的返回格式,通过固定的格式告诉他们什么时候接口是返回成功,什么时候返回失败,返回成功后他们如何拿到接口返回的数据去渲染前端页面。…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
