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 完事。

四、准备一点数据

显然,一个首页会有一个底部导航栏。一般而言会是"文字+图片"的组合,并且都具有选中状态、非选中状态。再显然这玩意是个数组。我们准备下

  1. 新建一个data/MainCategory.ets文件

    记得新建一个data文件夹

    简单的在里面定义一个数据结构

    kotlin 复制代码
     // 定义一个接口来表示项目类别的结构。
     export interface ItemCategory {
         // 当类别被选中时显示的图像资源。
         // 图像文件的引用
         selectedImage: Resource,
         // 未被选中时显示的图像资源。
         // 用于在用户界面上区分选中和未选中的状态。
         unselectedImage: Resource,
         // 类别的标题资源。
         // 一个字符串资源的引用
         title: Resource
     }

    贴心的加上注释。PS:export表示某个实体(比如一个类、接口、变量或函数)应该被导出,使得它可以在其他文件或模块中被导入和使用。

  2. 构造一丢丢数据

    我们打算做四个页面,所以准备四个数据吧~

    css 复制代码
     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:如果变量引用的是一个对象或数组,那么对象的属性或数组的元素是可以被修改)。

  3. 温柔的导入

    回到我们的Index.ets。让我们导入刚刚准备的数据~

    javascript 复制代码
     import { ItemCategory, MAIN_CATEGORIES } from './data/MainCategory'

    import就是导入的意思,这玩意一般在文件的最前面。

    {}用来声明你要导入这个文件中的什么(PS:这玩意能换名字)

    javascript 复制代码
     import { ItemCategory, MAIN_CATEGORIES as NewName} from './data/MainCategory'

    from 显然没什么用

    ./聪明的你,很清楚的知道这玩意的意思是:表示当前文件所在目录。顺带还想到了../表示:父目录。那还有......../?抱歉,没有了。但是你可以这么写

    javascript 复制代码
     import { ItemCategory, MAIN_CATEGORIES as NewName} from '../../main/ets/data/MainCategory'

    这样你就可以无限套娃了~一直../下去吧!少年!

五、准备好Tab

首先,肯定有当前展示页面之分,所以我们需要记录下选中的页面的Tab的Index

css 复制代码
 @State tabCurrentIndex: number = 0

PS:@State装饰的状态变量,一旦变量拥有了状态属性,就和自定义组件的渲染绑定起来。当状态改变时,UI会发生对应的渲染改变(官网抄的)。

我们直接使用鸿蒙之超能Tab之Tab,

typescript 复制代码
 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

scss 复制代码
 // 使用 @Builder 装饰器,表示 TabBarBuilder 是一个构建器方法
 @Builder
 TabBarBuilder(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组件里面一塞

kotlin 复制代码
 tabBar(this.TabBarBuilder(index, item.selectedImage, item.unselectedImage, item.title))

那么Tab就完成啦~~~

六、TabContent

重要的页面来了。

为了不让Index内太臃肿,我们直接!新建一个 MainPageContainer类,并塞入一个Text

scss 复制代码
 @Component
 export 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中导入一下

javascript 复制代码
 import { MainPageContainer } from './MainPageContainer'

再这么一用

scss 复制代码
 TabContent() {
     MainPageContainer({ mTitle: item.title })
 }

完事~

最后效果放在最前面啦~

七、总结

这玩意挺简单了,但是这DevEco-Studio是我用过的最垃圾的工具了。真的烂。这代码提醒,这代码补全,不如不要,啥也提醒不了,就只会"Did you mean xxxx"、"ignore x x x x"。💩。

代码放在这了,你点一下

如果您有任何疑问、对文章写的不满意、发现错误或者有更好的方法,欢迎在评论、私信或邮件中提出,非常感谢您的支持。🙏

八、感谢

感谢TMD鸿蒙。

相关推荐
Jouzzy7 小时前
【Android安全】Ubuntu 16.04安装GDB和GEF
android·ubuntu·gdb
极客先躯7 小时前
java和kotlin 可以同时运行吗
android·java·开发语言·kotlin·同时运行
小强在此9 小时前
【基于开源鸿蒙(OpenHarmony)的智慧农业综合应用系统】
华为·开源·团队开发·智慧农业·harmonyos·开源鸿蒙
Good_tea_h10 小时前
Android中的单例模式
android·单例模式
PlumCarefree12 小时前
基于鸿蒙API10的RTSP播放器(四:沉浸式播放窗口)
华为·harmonyos
计算机源码社15 小时前
分享一个基于微信小程序的居家养老服务小程序 养老服务预约安卓app uniapp(源码、调试、LW、开题、PPT)
android·微信小程序·uni-app·毕业设计项目·毕业设计源码·计算机课程设计·计算机毕业设计开题
丶白泽15 小时前
重修设计模式-结构型-门面模式
android
中关村科金16 小时前
中关村科金推出得助音视频鸿蒙SDK,助力金融业务系统鸿蒙化提速
华为·音视频·harmonyos
晨春计16 小时前
【git】
android·linux·git