玩转HarmonyOS NEXT之IM应用首页布局
本文从目前流行的垂类市场中,选择即时通讯应用作为典型案例详细介绍HarmonyOS NEXT的各类布局在实际开发中的综合应用。即时通讯应用的核心功能为用户交互,主要包含对话聊天、通讯录,社交圈等交互功能。
应用首页
创建一个包含一列的栅格布局,显示文本“首页”,并且监听断点变化,当断点发生变化时更新 currentBreakpoint状态。
- 示例代码
@Entry @Component struct Index {@StorageLink('currentBreakpoint') currentBreakpoint: string = 'sm';build() {GridRow({ columns: 1 }) {GridCol({ span: 1 } ) {Column() {Text('首页')}.width('100%').height('100%')}}.onBreakpointChange((breakPoint => {this.currentBreakpoint = breakPoint;}))} }
装饰器
@Entry:标记这是一个页面入口@Component:标记这是一个组件
状态管理
@StorageLink:全局UI状态存储。currentBreakpoint:声明并初始化了一个字符串类型的状态变量,初始值为 ‘sm’,这可能表示屏幕宽度的断点。
布局和结构
GridRow和GridCol:表示一个栅格布局,GridRow包含一行,GridCol表示该行中的一列。columns: 1和span: 1:指定网格布局中的列数和列的跨度。
断点变化处理
.onBreakpointChange:绑定一个事件处理函数,当断点变化时触发。(breakPoint => { this.currentBreakpoint = breakPoint; }):定义了一个箭头函数,将新的断点值赋给currentBreakpoint。
HomeTab组件
BottomNavigation构造器
BottomNavigation构建器函数用于创建一个带有图像和文本的底部导航按钮,具有自适应布局和状态变化的功能。通过点击按钮,可以更新当前页面索引,从而改变按钮的显示状态(例如图像和文本的颜色)。
- 示例代码
interface BottomNavigationProps {index: number;img: Resource;selectImg?: Resource;title: Resource | string;
}@BuilderBottomNavigation(button: BottomNavigationProps) {Column() {Image(this.currentPageIndex === button.index ? button.selectImg : button.img).objectFit(ImageFit.Contain).width(this.currentBreakpoint === 'lg' ? '24vp' : '22vp').height(this.currentBreakpoint === 'lg' ? '24vp' : '22vp')Text(button.title).fontColor(this.currentPageIndex === button.index ? '#0A59F7' : Color.Black).opacity(this.currentPageIndex === button.index ? 1 : 0.6).fontWeight(500).textAlign(TextAlign.Center).fontSize('10fp').lineHeight('14vp').fontFamily('HarmonyHeiTi-Bold').margin({ top: '4vp' })}.alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center).onClick(() => {this.currentPageIndex = button.index;})}
}
参数类型约束
interface BottomNavigationProps {index: number;img: Resource;selectImg?: Resource;title: Resource | string;
}
index:按钮的索引,用于标识按钮。img:按钮的默认图像资源。selectImg:按钮的选中状态图像资源(可选)。title:按钮的标题,可以是资源或字符串。
构造器函数
@Builder
BottomNavigation(button: BottomNavigationProps) {
@Builder:表示这是一个构建器函数,用于构建UI组件。BottomNavigation(button: BottomNavigationProps):定义了接收一个 BottomNavigationProps 类型的参数 button。
组件布局
Column() {Image(this.currentPageIndex === button.index ? button.selectImg : button.img).objectFit(ImageFit.Contain).width(this.currentBreakpoint === 'lg' ? '24vp' : '22vp').height(this.currentBreakpoint === 'lg' ? '24vp' : '22vp')
Column():创建一个列布局,用于垂直排列组件。Image(...):根据当前页面索引和按钮索引是否匹配来选择显示按钮的图像或选中状态的图像。objectFit(ImageFit.Contain):设置图像的适应方式为“Contain”。.width(...) 和 .height(...):根据断点调整图像的宽度和高度。
文本设置
Text(button.title).fontColor(this.currentPageIndex === button.index ? '#0A59F7' : Color.Black).opacity(this.currentPageIndex === button.index ? 1 : 0.6).fontWeight(500).textAlign(TextAlign.Center).fontSize('10fp').lineHeight('14vp').fontFamily('HarmonyHeiTi-Bold').margin({ top: '4vp' })
Text(button.title):显示按钮的标题。.fontColor(...):根据按钮是否被选中设置字体颜色。.opacity(...):根据按钮是否被选中设置透明度。.fontWeight(500):设置字体粗细。.textAlign(TextAlign.Center):设置文本对齐方式为居中。.fontSize('10fp') 和 .lineHeight('14vp'):设置字体大小和行高。.fontFamily('HarmonyHeiTi-Bold'):设置字体样式。margin({ top: '4vp' }):设置顶部外边距。
列对齐和点击事件
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.onClick(() => {this.currentPageIndex = button.index;
})
.alignItems(HorizontalAlign.Center):设置列交叉轴居中对齐。.justifyContent(FlexAlign.Center):设置列主轴居中对齐。.onClick(...):绑定点击事件处理函数,当按钮被点击时更新 currentPageIndex 为按钮的索引。
HomeTab布局
构建了一个包含底部导航栏的界面布局。使用Tabs和TabContent组件来构建一个带有多个标签页的布局,每个标签页都通过BottomNavigation函数生成按钮,这些按钮包含图像和文本,并且具有自适应布局和状态变化的功能。通过点击标签页按钮,可以更新currentPageIndex,从而改变当前显示的页面内容。
- 示例代码
interface BottomNavigationProps {index: number;img: Resource;selectImg?: Resource;title: Resource | string;
}@Component
export default struct HomeTab {@StorageProp('currentBreakpoint') currentBreakpoint: string = 'sm';@Link currentPageIndex: number;build() {Column() {Tabs({ barPosition: this.currentBreakpoint === 'lg' ? BarPosition.Start : BarPosition.End }) {TabContent().tabBar(this.BottomNavigation({index: 0,img: $r('app.media.icon_message'),selectImg: $r('app.media.icon_message_selected'),title: '消息'}))TabContent().tabBar(this.BottomNavigation({index: 1,img: $r('app.media.icon_contacts'),selectImg: $r('app.media.icon_contacts_selected'),title: '通讯录'}))TabContent().tabBar(this.BottomNavigation({index: 2,img: $r("app.media.icon_social_circle"),selectImg: $r("app.media.icon_social_circle_selected"),title: '朋友圈'}))TabContent().tabBar(this.BottomNavigation({index: 3,img: $r('app.media.icon_me'),selectImg: $r('app.media.icon_me'),title: '我的'}))}.vertical(this.currentBreakpoint === 'lg').height('100%').margin({top: this.currentBreakpoint === 'lg' ? '' : '6.5vp',bottom: this.currentBreakpoint === 'lg' ? '' : '7.5vp'})}.backgroundColor('#F1F3F5').expandSafeArea([], [SafeAreaEdge.BOTTOM])}@BuilderBottomNavigation(button: BottomNavigationProps) {Column() {Image(this.currentPageIndex === button.index ? button.selectImg : button.img).objectFit(ImageFit.Contain).width(this.currentBreakpoint === 'lg' ? '24vp' : '22vp').height(this.currentBreakpoint === 'lg' ? '24vp' : '22vp')Text(button.title).fontColor(this.currentPageIndex === button.index ? '#0A59F7' : Color.Black).opacity(this.currentPageIndex === button.index ? 1 : 0.6).fontWeight(500).textAlign(TextAlign.Center).fontSize('10fp').lineHeight('14vp').fontFamily('HarmonyHeiTi-Bold').margin({ top: '4vp' })}.alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center).onClick(() => {this.currentPageIndex = button.index;})}
}
Link状态存储
@Link currentPageIndex: number;
@Link:标记currentPageIndex为一个Link状态变量,子组件中被@Link装饰的变量与其父组件中对应的数据源建立双向数据绑定。currentPageIndex:当前页面的索引。
标签页
Tabs({ barPosition: this.currentBreakpoint === 'lg' ? BarPosition.Start : BarPosition.End }) {
Tabs:创建一个标签页组件。barPosition:根据当前断点设置标签栏的位置,如果断点为lg,则标签栏位置为Start,否则为End。
安全区域
.backgroundColor('#F1F3F5')
.expandSafeArea([], [SafeAreaEdge.BOTTOM])
.expandSafeArea([], [SafeAreaEdge.BOTTOM]):扩展安全区域到底部,确保内容不会被系统导航栏遮挡。
实现效果图

参考文章
- 栅格布局
- 线性布局
- 全局状态存储
- Tabs
相关文章:
玩转HarmonyOS NEXT之IM应用首页布局
本文从目前流行的垂类市场中,选择即时通讯应用作为典型案例详细介绍HarmonyOS NEXT的各类布局在实际开发中的综合应用。即时通讯应用的核心功能为用户交互,主要包含对话聊天、通讯录,社交圈等交互功能。 应用首页 创建一个包含一列的栅格布…...
GPT-4o大语言模型优化、本地私有化部署、从0-1搭建、智能体构建
原文链接:GPT-4o大语言模型优化、本地私有化部署、从0-1搭建、智能体构建https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247608565&idx3&snd4e9d447efd82e8dd8192f7573886dab&chksmfa826912cdf5e00414e01626b52bab83a96199a6bf69cbbef7f7fe…...
记录些MySQL题集(4)
1、数据库的三范式是什么? 第一范式:列不可再分 第二范式:在第一范式的基础上,要求数据库表中的所有非主键列完全依赖于主键,而不是仅依赖于主键的一部分 第三范式:满足第二范式的基础上,所有…...
pdf提取其中一页怎么操作?提取PDF其中一页的方法
pdf提取其中一页怎么操作?需要从一个PDF文件中提取特定页码的操作通常是在处理文档时常见的需求。这种操作允许用户选择性地获取所需的信息,而不必操作整个文档。通过选择性提取页面,你可以更高效地管理和利用PDF文件的内容,无论是…...
godot使用ws
go服务端 package mainimport ("encoding/json""fmt""github.com/gorilla/websocket""net/http" )var upgrader websocket.Upgrader{ReadBufferSize: 1024,WriteBufferSize: 1024, }// 处理函数 func handleWebSocket(w http.Respo…...
Windows FFmpeg 开发环境搭建
FFmpeg 开发环境搭建 FFmpeg命令行环境搭建使用FFmpeg官方编译的库Windows编译FFmpeg1. 下载[msys2](https://www.msys2.org/#installation)2. 安装完成之后,将安装⽬录下的msys2_shell.cmd中注释掉的 rem set3. 修改pacman 镜像源并安装依赖4. 下载并编译源码 FFmpeg命令行环境…...
链路聚合概述
目录 技术背景: 基本概念: 链路聚合的工作模式: 简介: 1)Manual Load-balance(手动负载分担) 简介: 配置实施: 2)LACP(链路聚合控制协议ÿ…...
【链表】算法题(二) ----- 力扣/牛客
一、链表的回文结构 思路: 找到链表的中间节点,然后逆置链表的后半部分,再一一遍历链表的前半部分和后半部分,判断是是否为回文结构。 快慢指针找到链表的中间节点 slow指针指向的就是中间节点 逆置链表后半部分 逆置链表后半部分…...
合成复用原则
合成复用原则 (Composite Reuse Principle, CRP) 合成复用原则(Composite Reuse Principle, CRP),也被称为组合/聚合复用原则,是面向对象设计中的一条重要原则。它的核心思想是:优先使用对象组合/聚合,而不…...
安卓自带camera hal3 实例README.md翻译
最近,遇到一个这样的问题,临时了解下这个驱动实现架构和特点,翻译如下 V4L2相机HALv3 camera.v4l2库使用视频Linux 2(V4L2)接口实现了camera HAL v3。这使得它在理论上可以与各种设备配合使用,尽管V4L2的…...
ActiViz实战:ActiViz中的自己实现鼠标双击事件
文章目录 1、添加鼠标事件2、网上实现双击事件的方式3、增加双击的时间限制4、补充说明1、添加鼠标事件 已知在C#中观察者/命令模式会报错,正常添加鼠标事件如下: private void VtkInteractorStyleTest() {vtkInteractorStyle style = vtkInteractorStyle.New();style.LeftB…...
Linux-交换空间(Swap)管理
引入概念 在计算机中,硬盘的容量一般比内存大,内存(4GB 8GB 16GB 32GB 64GB…),硬盘(512GB 1T 2T…)。 冯诺依曼的现代计算机结构体系里面的存储器就是内存 内存是一种易失性存储器,…...
扫描某个网段下存活的IP:fping
前言: 之前用arp统计过某网段下的ip,但是有可能统计不全。网络管理平台又不允许登录。想要知道当前的ip占用情况,可以使用fping fping命令类似于ping,但比ping更强大。与ping需要等待某一主机连接超时或发回反馈信息不同&#x…...
【深度学习】PyTorch框架(3):优化与初始化
1.引言 在本文中,我们将探讨神经网络的优化与初始化技术。随着神经网络深度的增加,我们会遇到多种挑战。最关键的是确保网络中梯度流动的稳定性,否则可能会遭遇梯度消失或梯度爆炸的问题。因此,我们将深入探讨以下两个核心概念&a…...
Go-知识测试-子测试
Go-知识测试-子测试 1. 介绍2. 例子3. 子测试命名规则4. 选择性执行5. 子测试并发6. testing.T.Run7. testing.T.Parallel8. 子测试适用于单元测试9. 子测试适用于性能测试10. 总结10.1 启动子测试 Run10.2 启动并发测试 Parallel 建议先看:https://blog.csdn.net/a…...
.net core IConfiguration 读 appsettings.json 数据,举例
在.NET Core中,IConfiguration 接口是用来读取配置数据的,包括从 appsettings.json 文件中读取。下面是一个如何在使用.NET Core时通过 IConfiguration 读取 appsettings.json 数据的示例。 首先,假设你的 appsettings.json 文件内容如下&am…...
全球Windows机器蓝屏,作为量化人,我的检讨来了
昨天下午,微软给大家放了个假。Windows又双叒死机了。不过,这一次不是几台机器,而是全球大范围宕机。这一刻,大家都是“正蓝旗”。 蓝瓶的,效果好! 现在根本原因已经找到,绝大多数人的机器都已修…...
部署和运维
目录 1.Git1.1. Git指令中merge和rebase的区别1. Commit 记录2. 合并方式3. 冲突处理4. 使用场景选择建议 1.2. cherry-pick的使用如何使用 git cherry-pick例子处理冲突撤销 cherry-pick其他选项 结论 2. 部署1. Nginx的使用场景 编译打包1. webpack2. webpack打包优化1. 代码…...
微信小程序基本语法
官网 https://developers.weixin.qq.com/miniprogram/dev/framework/ 视频教程:尚硅谷微信小程序开发教程,2024最新微信小程序项目实战! 仿慕尚花坊项目源码:https://gitee.com/abcdfdewrw/flower-workshop 目录 一,初…...
测试用例的设计方法
等价类 等价类概念:在所有测试的数据中,具有某种共同特征的数据子集 边界值 边界值分析是对程序输入或输出的边界值进行测试的一种黑盒测试方法 边界值是作为等价类的补充,其主要区别是: 边界值测试设计不是从某一个等价类中…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
