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

鸿蒙:使用断点和媒体查询实现响应式布局

1. 前言

断点,可以理解为划分不同屏幕尺寸的工具,也可以理解为将屏幕尺寸归为一个范围点。做断点的目的是,方便我们在不同屏幕尺寸的鸿蒙设备下实现响应式UI布局。何为响应式布局,我的理解是,屏幕尺寸变化,你的UI会发生变化,以实现最佳的视觉效果,这就是响应式布局。

2. 核心思路

  1. 用媒体查询接口做横竖屏切换功能。
  2. 根据官方文档推荐的vp尺寸,合理划分屏幕所处的断点,例如:'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'。
  3. UI依据断点的变化,布局发生变化。

3. 核心代码

// 获取屏幕纵向断点str
getHeightBreakpointStr() {// HEIGHT_SM  0  窗口高宽比小于0.8。// HEIGHT_MD  1  窗口高宽比大于等于0.8,且小于1.2。// HEIGHT_LG  2  窗口高宽比大于等于1.2。const heightBreakpoint = this.getUIContext().getWindowHeightBreakpoint()console.info(` heightBreakpoint: ${heightBreakpoint}`);switch (heightBreakpoint) {case 0:this.heightBreakpoint = "sm"break;case 1:this.heightBreakpoint = "md"break;case 2:this.heightBreakpoint = "lg"break;default:break;}this.heightBreakpoint
}// 获取屏幕横向断点str
getWidthBreakpointStr() {//  获取当前实例所在窗口的宽度断点枚举值// WIDTH_XS 0  窗口宽度小于320vp。// WIDTH_SM 1  窗口宽度大于等于320vp,且小于600vp。// WIDTH_MD 2  窗口宽度大于等于600vp,且小于840vp。// WIDTH_LG 3  窗口宽度大于等于840vp,且小于1440vp。// WIDTH_XL 4  窗口宽度大于等于1440vp。const widthBreakpoint = this.getUIContext().getWindowWidthBreakpoint()console.info(` widthBreakpoint: ${widthBreakpoint}`);switch (widthBreakpoint) {case 0:this.widthBreakpoint = "xs"break;case 1:this.widthBreakpoint = "sm"break;case 2:this.widthBreakpoint = "md"break;case 3:this.widthBreakpoint = "lg"break;case 4:this.widthBreakpoint = "xl"break;default:break;}}

4. 运行效果

5. 完整代码

Index.ets

import { mediaquery, window } from '@kit.ArkUI';type BreakpointType = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl';@Entry
@ComponentV2
struct Index {@Local currentState: string = ""listener: mediaquery.MediaQueryListener =this.getUIContext().getMediaQuery().matchMediaSync('(orientation: landscape)');// 获取当前应用的UIAbility上下文context = this.getUIContext().getHostContext()!;@Local widthBreakpoint: BreakpointType = "xs"@Local heightBreakpoint: BreakpointType = "xs"aboutToAppear(): void {// 监听屏幕方向改变this.getCurrentOrientation()}// 获取屏幕纵向断点strgetHeightBreakpointStr() {// HEIGHT_SM  0  窗口高宽比小于0.8。// HEIGHT_MD  1  窗口高宽比大于等于0.8,且小于1.2。// HEIGHT_LG  2  窗口高宽比大于等于1.2。const heightBreakpoint = this.getUIContext().getWindowHeightBreakpoint()console.info(` heightBreakpoint: ${heightBreakpoint}`);switch (heightBreakpoint) {case 0:this.heightBreakpoint = "sm"break;case 1:this.heightBreakpoint = "md"break;case 2:this.heightBreakpoint = "lg"break;default:break;}this.heightBreakpoint}// 获取屏幕横向断点strgetWidthBreakpointStr() {//  获取当前实例所在窗口的宽度断点枚举值// WIDTH_XS 0  窗口宽度小于320vp。// WIDTH_SM 1  窗口宽度大于等于320vp,且小于600vp。// WIDTH_MD 2  窗口宽度大于等于600vp,且小于840vp。// WIDTH_LG 3  窗口宽度大于等于840vp,且小于1440vp。// WIDTH_XL 4  窗口宽度大于等于1440vp。const widthBreakpoint = this.getUIContext().getWindowWidthBreakpoint()console.info(` widthBreakpoint: ${widthBreakpoint}`);switch (widthBreakpoint) {case 0:this.widthBreakpoint = "xs"break;case 1:this.widthBreakpoint = "sm"break;case 2:this.widthBreakpoint = "md"break;case 3:this.widthBreakpoint = "lg"break;case 4:this.widthBreakpoint = "xl"break;default:break;}}/// 获取当前方向状态getCurrentOrientation() {this.listener.on('change', (mediaQueryResult: mediaquery.MediaQueryResult) => {console.log("监听结果" + mediaQueryResult.media)this.getWidthBreakpointStr()this.getHeightBreakpointStr()if (mediaQueryResult.matches) {this.currentState = "横屏"} else {this.currentState = "竖屏"}});}/// 切换横屏switchToLandscape() {// 获取应用的最后一个窗口实例window.getLastWindow(this.context).then((lastWindow) => {// 根据参数设置窗口首选方向:横屏lastWindow.setPreferredOrientation(window.Orientation.LANDSCAPE)});}/// 切换竖屏switchToPortrait() {// 获取应用的最后一个窗口实例window.getLastWindow(this.context).then((lastWindow) => {// 根据参数设置窗口首选方向:竖屏lastWindow.setPreferredOrientation(window.Orientation.PORTRAIT)});}build() {Column({ space: this.currentState == "横屏" ? 20 : 50 }) {Text("响应式布局:断点+媒体查询").fontSize(this.currentState == "横屏" ? 16 : 24).fontWeight(FontWeight.Bold)Column({ space: 30 }) {Text("宽度断点" + this.widthBreakpoint).fontSize(30).fontWeight(FontWeight.Bold)Text("纵向断点" + this.heightBreakpoint).fontSize(30).fontWeight(FontWeight.Bold)Text("当前的状态:" + this.currentState).fontSize(30).fontWeight(FontWeight.Bold)}Column({ space: 20 }) {Button("点击切换横屏").onClick(() => {this.switchToLandscape()}).backgroundColor(this.currentState == "横屏" ? Color.Black : Color.Blue)Button("点击切换竖屏").onClick(() => {this.switchToPortrait()}).backgroundColor(this.currentState == "横屏" ? Color.Black : Color.Blue)}Row({ space: this.widthBreakpoint == "sm" ? 20 : 50 }) {Image($r('app.media.startIcon')).width(this.widthBreakpoint == "sm" ? 20 : 50)Image($r('app.media.startIcon')).width(this.widthBreakpoint == "sm" ? 20 : 50)Image($r('app.media.startIcon')).width(this.widthBreakpoint == "sm" ? 20 : 50)Image($r('app.media.startIcon')).width(this.widthBreakpoint == "sm" ? 20 : 50)Image($r('app.media.startIcon')).width(this.widthBreakpoint == "sm" ? 20 : 50)Image($r('app.media.startIcon')).width(this.widthBreakpoint == "sm" ? 20 : 50)Image($r('app.media.startIcon')).width(this.widthBreakpoint == "sm" ? 20 : 50)}.justifyContent(FlexAlign.Center).width("100%")}.justifyContent(FlexAlign.Center).width("100%").height("100%")}
}

觉得有帮助,可以点赞或收藏

http://www.dtcms.com/a/492319.html

相关文章:

  • 个人网站备案可以做博客吗网站开发工作室 建设 方案
  • MySQL实战篇08:MySQL主从复制环境修复记录---3个真实问题的排查过程
  • asp.net mvc 5网站开发之美wordpress迁移到本地
  • 建站系统源码黑龙江交通系统网站建设
  • 万网网站制作学软件开发需要多少钱
  • RHCSA复习练习题
  • SEO vs AI 优化(GEO):跨境电商谁能带来更高流量增长?
  • 网站文件下载系统wordpress 优秀网站
  • 石家庄网站建设排名沈阳网页建站模板
  • 做智慧教室的网站家用电脑进行网站建设
  • 双分布函数热 LBM 模拟二维封闭方腔自然对流
  • 网站搭建 里短信asp wordpress
  • 做公司网站需注意什么装修设计装饰
  • 如何做好接口测试
  • 谈谈你对 Activity.runOnUiThread 的理解?
  • Bootstrap 5 响应式网站首页模板
  • 朝阳区北京网站建设怎么用flash做游戏下载网站
  • 在 FastAPI 项目中集成 FastMCP:完整指南与生命周期管理
  • /dev/null 是什么,有什么用途?
  • 原子核外电子排布的量子规律:从薛定谔方程到电子排布——薛定谔方程在球坐标系下的求解
  • 微信如何做网站网站备案注销
  • 做网站就要租服务器如何新建一个网站
  • MSTP 练习
  • 网站正在建设页面模板装饰公司门头
  • GPT-oss + vLLM + LobalChat
  • 外包网站建设是什么意思超级门户wordpress企业主题
  • 文本增强:回译技术,小数据集怎样扩充?
  • 动态业务需求下的突围——六款AI数据分析工具全景测评
  • MinerU2.5:高分辨率文档解析的解耦式视觉语言模型革命
  • 怎样建设商城网站淘宝店群软件定制开发