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

【HarmonyOS NEXT】一次开发多端部署(以轮播图、Tab栏、列表为例,配合栅格布局与媒体查询,进行 UI 的一多开发)

关键词:一多、响应式、媒体查询、栅格布局、断点、UI

随着设备形态的逐渐增多,应用界面适配也面临着很大问题,在以往的安卓应用开发过程中,往往需要重新开发一套适用于大屏展示的应用,耗时又耗力,而鸿蒙提供响应式开发的解决方案,提供系统级的接口供开发者调用,从而使得一款应用一套代码能同时运行在不同形态的设备上,也能给用户带来很好的交互体验。

本期文章以轮播图、Tab栏、列表为例,配合栅格布局与媒体查询,进行 UI 的一多开发。

本期完整代码已提交至gitee:one2More: 【HarmonyOS NEXT】一次开发多端部署(以轮播图、Tab栏、列表为例,配合栅格布局与媒体查询,进行 UI 的一多开发)

目录

效果预览

1. 了解断点、媒体查询、栅格布局

断点

媒体查询

栅格布局

2. 封装媒体查询监听断点工具类

3. 配合媒体查询做 Swiper() 轮播图分割效果

4. 配合媒体查询做 Tab 栏 UI 展示位置变动

5. 配合栅格布局做列表展示数量控制

总结

效果预览

 普通屏

 折叠屏

 大屏

1. 了解断点、媒体查询、栅格布局

断点

鸿蒙提供断点以应用窗口宽度为切入点,将应用窗口在宽度维度上分成了几个不同的区间即不同的断点,不同设备会进入到不同的断点区间,在不同的区间下,我们可以可根据需要实现不同的页面布局效果。具体的断点对应的设备尺寸如下所示。

断点名称取值范围(vp)
xs[0, 320)
sm[320, 600)
md[600, 840)
lg[840, +∞)

媒体查询

媒体查询支持监听窗口宽度、横竖屏、深浅色、设备类型等多种媒体特征,当媒体特征发生改变时同步调整页面布局。我们可以借助媒体查询能力,监听断点的变化。

栅格布局

栅格组件默认提供xs、sm、md、lg四个断点,除了默认的四个断点,还支持启用 xl 和 xxl 两个额外的断点,我们只需要在 GridRow() 组件的 breakpoints 属性中依次设置对应断点的尺寸,可自行对断点设备的尺寸进行设置从而满足自己尺寸的业务需求,当然还是更推荐使用默认的断点尺,如果使用到媒体查询,和自定义尺寸保持一致即可。

breakpoints 数组中最大可写 5 个尺寸,对应 6 个断点范围,且断点值后面必须加上vp单位。

reference 属性代表 GridRow 宽度变化随屏幕变化,还是随当前局部区域尺寸变化(因为在实际场景中,存在应用窗口尺寸不变但是局部区域尺寸发生了变化的情况,栅格组件支持以自身宽度为参照物响应断点变化具有更大的灵活性。)

栅格布局详细介绍请参考:文档中心

示例代码:

@Entry
@Component
struct GridRowSample1 {@State private currentBreakpoint: string = 'unknown'build() {// 修改断点的取值范围同时启用更多断点,注意,修改的断点值后面必须加上vp单位。GridRow({breakpoints: {value: ['600vp', '700vp', '800vp', '900vp', '1000vp'],reference: BreakpointsReference.WindowSize}}) {GridCol({span:{xs: 12, sm: 12, md: 12, lg:12, xl: 12, xxl:12}}) {Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {Text(this.currentBreakpoint).fontSize(50).fontWeight(FontWeight.Medium)}}}.onBreakpointChange((currentBreakpoint: string) => {this.currentBreakpoint = currentBreakpoint})}
}

2. 封装媒体查询监听断点工具类

给我们的业务封装媒体查询监听断点工具类,以便后续使用,在首页生命周期过程中进行调用初始化,利用 LocalStorage 或 AppStorage 保存当前屏幕断点的名称,在应用的任意页面内通过 StorageProp 获取并动态观察屏幕设备形态状态的变化从而更新页面 UI 的展示效果,如折叠屏形态下窄屏变宽屏的使用场景,这时的断点会由 sm 变为 md。

如下代码,监听了 sm、md、lg 三种设备形态,当设备形态变化,会重新写入 storage 数据,配合状态变量即可动态更新 UI

import mediaQuery from '@ohos.mediaquery';@Observed
export class MediaWatching {private sm: string = '(width<600vp)'private md: string = "(600vp<=width<840vp)"private lg: string = "(840vp<=width)"private type: 'sm' | 'md' | 'lg' = 'sm'init() {console.log("luvi > mediaQueryResult change " + this.type)// 小尺寸屏const smListener = mediaQuery.matchMediaSync(this.sm)smListener.on('change', (mediaQueryResult) => {this.onPortrait(mediaQueryResult)})// 中等尺寸屏const mdListener = mediaQuery.matchMediaSync(this.md)mdListener.on('change', (mediaQueryResult) => {this.onPortrait(mediaQueryResult)})// 大尺寸屏const lgListener = mediaQuery.matchMediaSync(this.lg)lgListener.on('change', (mediaQueryResult) => {this.onPortrait(mediaQueryResult)})}onPortrait(mediaQueryResult: mediaQuery.MediaQueryResult) {console.log("luvi > mediaQueryResult " + JSON.stringify(mediaQueryResult))if (mediaQueryResult.matches) {switch (mediaQueryResult.media as string) {case this.sm:this.type = 'sm'breakcase this.md:this.type = 'md'breakcase this.lg:this.type = 'lg'breakdefault:break}console.log("luvi > mediaQueryResult change " + this.type)AppStorage.setOrCreate("currentMediaType", this.type)}}
}

3. 配合媒体查询做 Swiper() 轮播图分割效果

在上一步的媒体查询封装及初始化后,屏幕设备形态变化后的名称会保存在 AppStorage 中,所以我们在自定义组件中可及时获取存入的 currentMediaType ,配合 Swiper 相关接口,使用 .displayCount() 设置 Swiper 视窗内元素显示个数达到分割效果。

@Component
export struct MySwiper {swiperList: number[] = [1, 2, 3, 4, 5]// 获取当前设备断点形态@StorageProp("currentMediaType") currentMediaType: 'sm' | 'md' | 'lg' = 'sm'build() {Column() {Swiper() {ForEach(this.swiperList, (item: number, idx: number) => {Row() {Text(`图片${item}`).textAlign(TextAlign.Center).width("100%")}.borderRadius(10).width("100%").height(250).backgroundColor(idx % 2 == 0 ? "#ddd" : "#ffb0b0b0")})}.itemSpace(10)// 根据断点设置分割个数// sm 小屏形态只展示 1 个,其他形态展示 2 个.displayCount(this.currentMediaType == "sm" ? 1 : 2).autoPlay(true).borderRadius(10).clip(true)}}
}

4. 配合媒体查询做 Tab 栏 UI 展示位置变动

Tab 栏位置的变化与轮播图分栏同理,配合 storage 状态变量获取设备形态,对不同设备形态更改 Tab 栏标签的排列方向即可。

详细 Tab 代码可参考 gitee 源代码

// 获取当前设备断点形态
@StorageProp("currentMediaType") currentMediaType: 'sm' | 'md' | 'lg' = 'sm'Tabs({ barPosition: BarPosition.End }) {TabContent() {// 标签页...}TabContent() {// 标签页...}TabContent() {// 标签页...}}// 对不同设备形态设置不同排列方向.vertical(this.currentMediaType == 'sm' || this.currentMediaType == 'md' ? false : true)

5. 配合栅格布局做列表展示数量控制

栅格布局拥有独立的断点能力,不依赖与媒体查询接口,所以直接使用栅格布局的特性进行开发即可。

栅格布局主要由行和列组成,每一行可以分为若干列,在不同断点状态下展示不同数量的列数,根据这一特性,即可制作成在小屏幕上展示一列文本,在大屏幕上展示两列甚至多列文本。

所以我们可以直接对 GridRow 设置对应断点时展示的 GridCol 个数即可,无需对 GridCol 设置额外参数

GridRow({columns: {xs: 1, // 超小屏幕 1 列(如手表)sm: 1, // 小屏幕 1 列md: 2, // 中等屏幕 2 列lg: 3  // 大屏幕 3 列},gutter: 15 // gutter 表示各元素直接间隙尺寸}) {ForEach(this.dataList, (item: number, idx: number) => {GridCol() {Row() {Text(`列表${item}`).textAlign(TextAlign.Center).width("100%")}.borderRadius(10).width("100%").height(130).backgroundColor("#eee")}})}

总结

栅格布局拥有独立的断点能力,不依赖与媒体查询接口,所以直接使用栅格布局的特性进行开发即可。

轮播图的分割效果与 Tab 栏的排列方式变化,同样可使用栅格布局进行实现,不用依赖媒体查询接口,因为栅格布局的 GridRow 组件有 onBreakpointChange 断点变化回调,可直接返回当组件宽度所在的断点区间。

GridRow(){...
}
.onBreakpointChange((bp: string) => {// 此处回调打印 xs / sm / md ...
})

相关文章:

【HarmonyOS NEXT】一次开发多端部署(以轮播图、Tab栏、列表为例,配合栅格布局与媒体查询,进行 UI 的一多开发)

关键词&#xff1a;一多、响应式、媒体查询、栅格布局、断点、UI 随着设备形态的逐渐增多&#xff0c;应用界面适配也面临着很大问题&#xff0c;在以往的安卓应用开发过程中&#xff0c;往往需要重新开发一套适用于大屏展示的应用&#xff0c;耗时又耗力&#xff0c;而鸿蒙提供…...

ubontu--cuDNN安装

1. 下载 cuDNN https://developer.nvidia.com/cudnn 2. 拷贝到服务器/home/<username>文件夹下 解压缩到当前文件夹&#xff1a; tar -xvf cudnn-linux-x86_64-9.5.1.17_cuda11-archive.tar.xz复制头文件和库文件到cuda安装目录/usr/local/cuda/ sudo cp /home/usern…...

高项 - 项目范围管理

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 博文更新参考时间点&#xff1a;2024-12 高项 - 章节与知识点汇总&#xff1a;点击跳转 文章目录 高项 - 项目范围管理范围管理ITO规划监控 管理基础产品范围与项目范围管理新实践 5大过程组与范围管理过程概述裁…...

如何获取PostgreSQL慢查询?从小白到高手的实战指南

数据库优化是性能调优的核心&#xff0c;而慢查询则是性能瓶颈的罪魁祸首。如何找到慢查询并优化它们&#xff0c;是每个开发者和DBA都必须掌握的技能。 今天&#xff0c;我们就来聊聊如何在PostgreSQL中快速获取慢查询日志&#xff0c;并结合不同场景进行分析优化。本文风格参…...

golang分布式缓存项目 Day4 一致性哈希

注&#xff1a;该项目原作者&#xff1a;https://geektutu.com/post/geecache-day1.html。本文旨在记录本人做该项目时的一些疑惑解答以及部分的测试样例以便于本人复习 为什么使用一致性哈希 我该访问谁 对于分布式缓存来说&#xff0c;当一个节点接收到请求&#xff0c;如…...

ARM 汇编指令

blr指令的基本概念和用途 在 ARM64 汇编中&#xff0c;blr是 “Branch with Link to Register” 的缩写。它是一种分支指令&#xff0c;主要用于跳转到一个由寄存器指定的地址&#xff0c;并将返回地址保存到链接寄存器&#xff08;Link Register&#xff0c;LR&#xff09;中。…...

打造个性化体验:在Axure中创建你的专属组件库

打造个性化体验&#xff1a;在Axure中创建你的专属组件库 在数字产品设计的浪潮中&#xff0c;效率和一致性是设计团队追求的两大圣杯。 随着项目的不断扩展&#xff0c;重复性的工作逐渐增多&#xff0c;设计师们开始寻找能够提高工作效率、保持设计一致性的解决方案。 而 …...

如何用WordPress和Shopify提升SEO表现?

选择合适的建站程序对于SEO优化非常重要。目前&#xff0c;WordPress和Shopify是两种备受推崇的建站平台&#xff0c;各有优势。 WordPress最大的优点是灵活性。它支持大量SEO插件&#xff0c;帮助你调整元标签、生成站点地图、优化内容结构等。这些功能让你能够轻松地提升网站…...

不泄密的安全远程控制软件需要哪些技术

在数字化浪潮中&#xff0c;远程控制软件已不再是简单的辅助工具&#xff0c;而是成为企业运作和日常工作中不可或缺的一部分。随着远程办公模式的广泛采纳&#xff0c;这些软件提供了一种既安全又高效的途径来管理和访问远端系统。无论是在家办公、技术支持还是远程教育&#…...

rust高级特征

文章目录 不安全的rust解引用裸指针裸指针与引用和智能指针的区别裸指针使用解引用运算符 *&#xff0c;这需要一个 unsafe 块调用不安全函数或方法在不安全的代码之上构建一个安全的抽象层 使用 extern 函数调用外部代码rust调用C语言函数rust接口被C语言程序调用 访问或修改可…...

STM32F407简单驱动步进电机(标准库)

配置 单片机型号&#xff1a;STM32F104ZGT6 步进电机&#xff1a;YK28HB40-01A 驱动器&#xff1a;YKD2204M-Plus 接线方式&#xff1a; pu&#xff1a;接对应的产生PWM的引脚&#xff0c;这里接PF9&#xff0c;对应TIM14_CH1通道&#xff01; pu-&#xff1a;接单片机的G…...

使用热冻结数据层生命周期优化在 Elastic Cloud 中存储日志的成本

作者&#xff1a;来自 Elastic Jonathan Simon 收集数据对于可观察性和安全性至关重要&#xff0c;而确保数据能够快速搜索且获得低延迟结果对于有效管理和保护应用程序和基础设施至关重要。但是&#xff0c;存储所有这些数据会产生持续的存储成本&#xff0c;这为节省成本创造…...

LeetCode131. 分割回文串(2024冬季每日一题 4)

给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是 回文串 。返回 s 所有可能的分割方案。 示例 1&#xff1a; 输入&#xff1a;s “aab” 输出&#xff1a;[[“a”,“a”,“b”],[“aa”,“b”]] 示例 2&#xff1a; 输入&#xff1a;s “a…...

万字长文解读深度学习——训练(DeepSpeed、Accelerate)、优化(蒸馏、剪枝、量化)、部署细节

&#x1f33a;历史文章列表&#x1f33a; 深度学习——优化算法、激活函数、归一化、正则化深度学习——权重初始化、评估指标、梯度消失和梯度爆炸深度学习——前向传播与反向传播、神经网络&#xff08;前馈神经网络与反馈神经网络&#xff09;、常见算法概要汇总万字长文解读…...

STM32—独立看门狗(IWDG)和窗口看门狗(WWDG)

概述&#xff1a; WDG(Watchdog) 看门狗&#xff0c;看门狗可以监控程序的运行状态&#xff0c;当程序因为设计漏洞、硬件故障、电磁干扰等原因&#xff0c;出现卡死或跑飞现象时&#xff0c;看门狗能计时复位程序&#xff0c;避免程序陷入长时间的罢工状态&#xff0c;保证系…...

ks8 本地化部署 F5-TTS

huggingface上有一个demo可以打开就能玩 https://huggingface.co/spaces/mrfakename/E2-F5-TTS 上传了一段懂王的演讲片段&#xff0c;然后在 generate text框内填了点古诗词&#xff0c;生成后这语气这效果&#xff0c;离真懂王就差一个手风琴了。 F5-TTS 项目地址&#xf…...

Web组态大屏可视化编辑器

1、零代码、一键构建、一键下载 用户只需通过拖拉拽操作&#xff0c;即可在画布上添加、调整和排列各种设备组件、图表和控件。零代码拖拽方式让用户能够实时预览界面效果&#xff0c;直观地观察布局、样式和数据的变化。 2、实时展示&#xff0c;自动化连接数据&#xff0c;用…...

【comfyui教程】让模特换衣服,comfyui一键搞定!

前言 一键穿上别人的衣服&#xff1f;揭秘ComfyUI模特换装工作流&#xff01; 你有没有想过&#xff0c;某天早晨你起床后&#xff0c;只需轻轻一点&#xff0c;就能穿上明星昨晚在红毯上的华丽礼服&#xff1f;这种听起来像是科幻电影的情节&#xff0c;如今通过ComfyUI模特…...

数据湖与数据仓库的区别

数据湖与数据仓库是两种不同的数据存储和管理方式&#xff0c;它们在多个方面存在显著的区别。以下是对数据湖与数据仓库区别的详细阐述&#xff1a; 一、数据存储方式 数据仓库 通常采用预定义的模式和结构来存储数据。数据在存储前通常经过清洗、转换和整合等处理&#xff0…...

golang分布式缓存项目 Day6 防止缓存击穿

该项目原作者&#xff1a;https://github.com/geektutu/7days-golang。本文旨在记录本人做该项目时的一些疑惑解答以及部分的测试样例以便于本人复习。 1 缓存雪崩、缓存击穿与缓存穿透 概念解析&#xff1a; 缓存雪崩&#xff1a;缓存在同一时刻全部失效&#xff0c;造成瞬…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...