当前位置: 首页 > news >正文

玩转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’,这可能表示屏幕宽度的断点。

布局和结构

  • GridRowGridCol:表示一个栅格布局,GridRow 包含一行,GridCol 表示该行中的一列。
  • columns: 1span: 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布局

构建了一个包含底部导航栏的界面布局。使用TabsTabContent组件来构建一个带有多个标签页的布局,每个标签页都通过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(链路聚合控制协议&#xff…...

【链表】算法题(二) ----- 力扣/牛客

一、链表的回文结构 思路: 找到链表的中间节点,然后逆置链表的后半部分,再一一遍历链表的前半部分和后半部分,判断是是否为回文结构。 快慢指针找到链表的中间节点 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…)。 冯诺依曼的现代计算机结构体系里面的存储器就是内存 内存是一种易失性存储器&#xff0c…...

扫描某个网段下存活的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 目录 一,初…...

测试用例的设计方法

等价类 等价类概念:在所有测试的数据中,具有某种共同特征的数据子集 边界值 边界值分析是对程序输入或输出的边界值进行测试的一种黑盒测试方法 边界值是作为等价类的补充,其主要区别是: 边界值测试设计不是从某一个等价类中…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...

React Native 导航系统实战(React Navigation)

导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…...

在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南

在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...