当前位置: 首页 > 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 目录 一,初…...

测试用例的设计方法

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

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...