一、背景
在渲染页面时,需要根据不同屏幕大小渲染出不同的效果,动态的判断设备屏幕大小,便需要采用多设备响应式布局。这种设计方法能够动态适配各种屏幕大小,确保网站在不同设备上都能呈现出最佳的效果。
二、媒体查询(mediaquery)
媒体查询作为响应式设计的核心,在移动设备上应用十分广泛。媒体查询可根据不同设备类型或同设备不同状态修改应用的样式。媒体查询常用于下面两种场景:
- 针对设备和应用的属性信息(比如显示区域、深浅色、分辨率),设计出相匹配的布局。
- 当屏幕发生动态改变时(比如分屏、横竖屏切换),同步更新应用的页面布局。
2.1、引入与使用流程
设备状态 | 媒体查询条件 |
SM | (320vp<=width<600vp) |
MD | (600vp<=width<840vp) |
LG | (840vp<=width) |
①导入媒体查询模块
import mediaquery from '@ohos.mediaquery';
②设置媒体查询条件,并获取对应的listener
let listener = mediaquery.matchMediaSync('(320vp<=width<600vp)');
③给listener设置回调函数,当设备状态变化时会执行回调函数
//设置监听回调函数
listener.on('change',result => {//判断是否满足媒体查询条件if(result.matches){//记录当前设备状态}
})
④将设备状态记录到全局状态中
AppStorage.SetOrCreate('currentBreakpoint','SM')
@StorageProp('currentBreakpoint') currentBreakpoint:string = 'SM'
2.2、具体实现
2.2.1、案例说明
⭐背景情况:在渲染页面时,不同屏幕大小渲染出效果是一样的,tabs都是在底部
⭐期望:根据不同屏幕大小渲染出不同的效果,tabs动态展示
2.2.2、实现步骤
①定义不同大小屏幕设备的Breakpoints 标记文件
import BreakpointType from '../bean/BreanpointType';
export default class BreakpointConstants {/*** 小屏幕设备的 Breakpoints 标记.*/static readonly BREAKPOINT_SM: string = 'sm';/*** 中等屏幕设备的 Breakpoints 标记.*/static readonly BREAKPOINT_MD: string = 'md';/*** 大屏幕设备的 Breakpoints 标记.*/static readonly BREAKPOINT_LG: string = 'lg';/*** 当前设备的 breakpoints 存储key*/static readonly CURRENT_BREAKPOINT: string = 'currentBreakpoint';/*** 小屏幕设备宽度范围.*/static readonly RANGE_SM: string = '(320vp<=width<600vp)';/*** 中屏幕设备宽度范围.*/static readonly RANGE_MD: string = '(600vp<=width<840vp)';/*** 大屏幕设备宽度范围.*/static readonly RANGE_LG: string = '(840vp<=width)';static readonly BAR_POSITION: BreakpointType<BarPosition> = new BreakpointType({sm: BarPosition.End,md: BarPosition.Start,lg: BarPosition.Start,})
}
②定义媒体查询工具类,用来完成监听器的自定义和使用,并将监听器进行存储
import mediaQuery from '@ohos.mediaquery';
import BreakpointConstants from '../constants/BreakpointConstants'export default class BreakpointSystem{//定义3个屏幕监听器private smListener: mediaQuery.MediaQueryListener = mediaQuery.matchMediaSync(BreakpointConstants.RANGE_SM)private mdListener: mediaQuery.MediaQueryListener = mediaQuery.matchMediaSync(BreakpointConstants.RANGE_MD)private lgListener: mediaQuery.MediaQueryListener = mediaQuery.matchMediaSync(BreakpointConstants.RANGE_LG)//定义回调函数smListenerCallback(result: mediaQuery.MediaQueryResult){if(result.matches){this.updateCurrentBreakpoint(BreakpointConstants.BREAKPOINT_SM)}}mdListenerCallback(result: mediaQuery.MediaQueryResult){if(result.matches){this.updateCurrentBreakpoint(BreakpointConstants.BREAKPOINT_MD)}}lgListenerCallback(result: mediaQuery.MediaQueryResult){if(result.matches){this.updateCurrentBreakpoint(BreakpointConstants.BREAKPOINT_LG)}}//定义存储函数,以上3个函数中调用updateCurrentBreakpoint(breakpoint: string){AppStorage.SetOrCreate(BreakpointConstants.CURRENT_BREAKPOINT, breakpoint)}//监听register(){this.smListener.on('change', this.smListenerCallback.bind(this))this.mdListener.on('change', this.mdListenerCallback.bind(this))this.lgListener.on('change', this.lgListenerCallback.bind(this))}//取消监听unregister(){this.smListener.off('change', this.smListenerCallback.bind(this))this.mdListener.off('change', this.mdListenerCallback.bind(this))this.lgListener.off('change', this.lgListenerCallback.bind(this))}
}/** 1、定义3个屏幕监听器* 2、分别监听不同的屏幕获取宽度范围* (先定义3个屏幕的函数,定义函数时使用AppStorage进行存储)+(再进行绑定,利用on监听,off取消监听)* */
③定义标记类型,页面中使用
//定义标记类型
declare interface BreakpointTypeOptions<T>{sm?:T,md?:T,lg?:T
}export default class BreakpointType<T>{options: BreakpointTypeOptions<T>constructor(options: BreakpointTypeOptions<T>) {this.options = options}getValue(breakpoint: string): T{return this.options[breakpoint]}
}
④在页面中使用,不同屏幕展示不同大小
说明:在首页中使用breakpointSystem完成初始化在当前组件构建之前,去调用,完成注册;在组件销毁时,完成取消注册
tabs根据不同屏幕大小来显示方向位置