HarmonyOS 鸿蒙Next应用开发基础架构搭建-多端布局之响应式布局

发布于 1周前 作者 songsunli 来自 鸿蒙OS

HarmonyOS 鸿蒙Next应用开发基础架构搭建-多端布局之响应式布局

响应式设计(Responsive Web Design,简称RWD)在web网站设计领域是一种网页设计方法论,旨在让网站在不同设备和屏幕尺寸上都能提供良好的阅读和交互体验,而无需为每一个新设备或屏幕尺寸创建单独的版本。这种设计方法的核心在于页面布局和内容可以根据用户所使用的设备特性(如屏幕尺寸、分辨率、方向)进行灵活调整。在web网站设计中,诞生了很多优秀的响应式UI框架,例如Bootstrap 响应式UI框架,通过媒体查询、断点控制以及内置的响应式组件,实现响应式页面布局。

cke_11768.png

cke_15564.png

Bootstrap中的断点

响应式设计在鸿蒙系统(HarmonyOS)中的应用主要体现在UI开发上,目的是确保应用能够在搭载鸿蒙系统的多种设备上,包括不同屏幕尺寸和分辨率的设备,提供一致且优化的用户体验。鸿蒙系统为此提供了一系列的响应式布局能力和工具,用来实现多端布局。

鸿蒙中的响应式设计特点包括:

  1. 栅格断点系统:鸿蒙系统提供了一套栅格系统,类似于Web设计中的栅格布局,帮助开发者定义页面布局在不同屏幕宽度下的断点。通过设置这些断点,应用可以在从小屏到大屏的不同设备上自动调整布局结构,以适应不同的显示需求。
  2. 媒体查询:类似于Web CSS中的媒体查询,鸿蒙系统允许开发者根据设备的特性(如屏幕尺寸、分辨率等)编写条件语句来应用不同的布局规则或样式。这样可以精确控制不同场景下的界面呈现。
  3. 响应式组件:鸿蒙内置的一些组件支持响应式布局,例如: Tabs、Swiper、Grid、List、GridRow,通过断点设置可以实现不同的展示效果。

断点

  断点以应用窗口宽度为切入点,将应用窗口在宽度维度上分成了几个不同的区间即不同的断点,在不同的区间下,开发者可根据需要实现不同的页面布局效果。

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

 鸿蒙中的断点

鸿蒙系统提供了多种方法,开发者判断当前是哪种断点,根据断点情况调整app的布局。

我们以媒体查询为例:

媒体查询通过mediaquery模块接口,设置查询条件并绑定回调函数,在对应的条件的回调函数里更改页面布局或者实现业务逻辑,实现页面的响应式设计。具体步骤如下:

1. 首先导入媒体查询模块。

import mediaquery from ‘@ohos.mediaquery’;<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

2. 通过matchMediaSync接口设置媒体查询条件,保存返回的条件监听句柄listener。例如监听横屏事件:

let listener: mediaquery.MediaQueryListener = mediaquery.matchMediaSync(’(orientation: landscape)’);<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

3. 给条件监听句柄listener绑定回调函数onPortrait,当listener检测设备状态变化时执行回调函数。在回调函数内,根据不同设备状态更改页面布局或者实现业务逻辑。

onPortrait(mediaQueryResult: mediaquery.MediaQueryResult) {
if (mediaQueryResult.matches as boolean) {
// do something here
} else {
// do something here
}
}

listener.on(‘change’, onPortrait);<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

媒体查询条件由媒体类型、逻辑操作符、媒体特征组成,其中媒体类型可省略,逻辑操作符用于连接不同媒体类型与媒体特征,其中,媒体特征要使用“()”包裹且可以有多个。

语法规则包括媒体类型(media-type)媒体逻辑操作(media-logic-operations)媒体特征(media-feature)

[media-type] [media-logic-operations] [(media-feature)]<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

例如:断点的写法

mediaquery.matchMediaSync(’(320vp<width<600vp)’)<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

根据媒体查询的基本使用方法,我们简单使用一下:

import mediaquery from ‘@ohos.mediaquery’
@Entry
@Component
struct Index {

@State currentBreakpoint: string = ‘md’; private xsListener: mediaquery.MediaQueryListener = mediaquery.matchMediaSync(’(0vp<width<320vp)’); private smListener: mediaquery.MediaQueryListener = mediaquery.matchMediaSync(’(320vp<width<600vp)’); private mdListener: mediaquery.MediaQueryListener = mediaquery.matchMediaSync(’(600vp<width<840vp)’); private lgListener: mediaquery.MediaQueryListener = mediaquery.matchMediaSync(’(840vp<=width)’);

registerBreakpoint(){ if (this.xsListener.matches) { this.updateCurrentBreakpoint(‘xs’) }

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.smListener.matches) {
  <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.updateCurrentBreakpoint(<span class="hljs-string"><span class="hljs-string">'sm'</span></span>)
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.mdListener.matches) {
  <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.updateCurrentBreakpoint(<span class="hljs-string"><span class="hljs-string">'md'</span></span>)
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.lgListener.matches) {
  <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.updateCurrentBreakpoint(<span class="hljs-string"><span class="hljs-string">'lg'</span></span>)
}

}

updateCurrentBreakpoint(breakpoint: string) { if (this.currentBreakpoint !== breakpoint) { this.currentBreakpoint = breakpoint; } }

aboutToAppear(): void { this.registerBreakpoint(); }

build() { RelativeContainer() { Text(this.currentBreakpoint) .id(‘HelloWorld’) .fontSize(50) .fontWeight(FontWeight.Bold) .alignRules({ center: { anchor: container, align: VerticalAlign.Center }, middle: { anchor: container, align: HorizontalAlign.Center } }) } .height(‘100%’) .width(‘100%’) } }<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

可以看到不同尺寸设备上,获取到的断点是不同的:

cke_127366.png

cke_131935.png

cke_137234.png

在鸿蒙的一些组件中内置了一些属性,可以根据不同的属性配置实现不同的布局展示,例如Tabs组件,通过barPosition、vertical的不同组合可以实现不同屏幕的适配。

cke_271673.png

结合前面的媒体查询断点代码和Tabs组件,通过代码具体实现一下:

build() {
Tabs({ barPosition: this.currentBreakpoint == ‘lg’ ? BarPosition.Start: BarPosition.End }) {
TabContent() {
Text(‘首页的内容’ + this.currentBreakpoint).fontSize(30)
}
.tabBar(‘首页’)

  TabContent() {
    Text(<span class="hljs-string"><span class="hljs-string">'推荐的内容'</span></span>).fontSize(<span class="hljs-number"><span class="hljs-number">30</span></span>)
  }
  .tabBar(<span class="hljs-string"><span class="hljs-string">'推荐'</span></span>)

  TabContent() {
    Text(<span class="hljs-string"><span class="hljs-string">'发现的内容'</span></span>).fontSize(<span class="hljs-number"><span class="hljs-number">30</span></span>)
  }
  .tabBar(<span class="hljs-string"><span class="hljs-string">'发现'</span></span>)

  TabContent() {
    Text(<span class="hljs-string"><span class="hljs-string">'我的内容'</span></span>).fontSize(<span class="hljs-number"><span class="hljs-number">30</span></span>)
  }
  .tabBar(<span class="hljs-string"><span class="hljs-string">"我的"</span></span>)
}
.vertical(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.currentBreakpoint == <span class="hljs-string"><span class="hljs-string">'lg'</span></span> ? <span class="hljs-literal"><span class="hljs-literal">true</span></span> : <span class="hljs-literal"><span class="hljs-literal">false</span></span>)
.barWidth(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.currentBreakpoint == <span class="hljs-string"><span class="hljs-string">'lg'</span></span> ? <span class="hljs-number"><span class="hljs-number">100</span></span> : <span class="hljs-string"><span class="hljs-string">''</span></span>)
.barHeight(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.currentBreakpoint == <span class="hljs-string"><span class="hljs-string">'lg'</span></span> ? <span class="hljs-number"><span class="hljs-number">200</span></span> : <span class="hljs-string"><span class="hljs-string">''</span></span>)

}<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

实现效果如下图:

cke_378547.png

cke_388904.png

cke_396094.png

可以看到在手机和折叠屏上tabbar在底部,在大屏平板上tabbar在右侧,这样方便用户手持平板操作。

在鸿蒙系统中,还有其他一些组件结合媒体查询可以实现不同的展示效果,例如: Swiper、Grid、List等,开发者可以根据这些组件构建多端布局。

HarmonyOS NEXT应用开发基础架构搭建-设计理念和目录结构

HarmonyOS NEXT应用开发基础架构搭建-模块设计

HarmonyOS NEXT应用开发基础架构搭建-路由管理

HarmonyOS NEXT应用开发基础架构搭建-路由页面权限控制

HarmonyOS NEXT应用开发基础架构搭建-多端布局之自适应布局

HarmonyOS NEXT应用开发基础架构搭建-多端布局之响应式布局



关于HarmonyOS 鸿蒙Next应用开发基础架构搭建-多端布局之响应式布局的问题,您也可以访问:https://www.itying.com/category-93-b0.html 联系官网客服。

2 回复

HarmonyOS的分布式文件系统让我在多设备间传输文件变得轻松无比。

讲的非常好 专业!
回到顶部