鸿蒙一次开发,多端部署(七)响应式布局

自适应布局可以保证窗口尺寸在一定范围内变化时,页面的显示是正常的。但是将窗口尺寸变化较大时(如窗口宽度从400vp变化为1000vp),仅仅依靠自适应布局可能出现图片异常放大或页面内容稀疏、留白过多等问题,此时就需要借助响应式布局能力调整页面结构。

响应式布局是指页面内的元素可以根据特定的特征(如窗口宽度、屏幕方向等)自动变化以适应外部容器变化的布局能力。响应式布局中最常使用的特征是窗口宽度,可以将窗口宽度划分为不同的范围(下文中称为断点)。当窗口宽度从一个断点变化到另一个断点时,改变页面布局(如将页面内容从单列排布调整为双列排布甚至三列排布等)以获得更好的显示效果。

当前系统提供了如下三种响应式布局能力,后文中我们将依次展开介绍。

断点

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

说明:

  • 以设备屏幕宽度作为参照物,也可以实现类似的效果。考虑到应用可能以非全屏窗口的形式显示,以应用窗口宽度为参照物更为通用。
  • 开发者可以根据实际使用场景决定适配哪些断点。如xs断点对应的一般是智能穿戴类设备,如果确定某页面不会在智能穿戴设备上显示,则可以不适配xs断点。
  • 可以根据实际需要在lg断点后面新增xl、xxl等断点,但注意新增断点会同时增加UX设计师及应用开发者的工作量,除非必要否则不建议盲目新增断点。

系统提供了多种方法,判断应用当前处于何种断点,进而可以调整应用的布局。常见的监听断点变化的方法如下所示:

  • 获取窗口对象并监听窗口尺寸变化
  • 通过媒体查询监听应用窗口尺寸变化
  • 借助栅格组件能力监听不同断点的变化

本小节中,先介绍如何通过窗口对象监听断点变化,后续的媒体查询及栅格章节中,将进一步展开介绍另外两种方法。

通过窗口对象监听断点变化的核心是获取窗口对象及注册窗口尺寸变化的回调函数。

  1. 在UIAbility的 onWindowStageCreate 生命周期回调中,通过 窗口 对象获取启动时的应用窗口宽度并注册回调函数监听窗口尺寸变化。将窗口尺寸的长度单位 由px换算为vp 后,即可基于前文中介绍的规则得到当前断点值,此时可以使用 状态变量 记录当前的断点值方便后续使用。
// MainAbility.ts
import window from '@ohos.window'
import display from '@ohos.display'
import UIAbility from '@ohos.app.ability.UIAbility'export default class MainAbility extends UIAbility {private windowObj?: window.Windowprivate curBp: string = ''//...// 根据当前窗口尺寸更新断点private updateBreakpoint(windowWidth: number) :void{// 将长度的单位由px换算为vplet windowWidthVp = windowWidth / display.getDefaultDisplaySync().densityPixelslet newBp: string = ''if (windowWidthVp < 320) {newBp = 'xs'} else if (windowWidthVp < 600) {newBp = 'sm'} else if (windowWidthVp < 840) {newBp = 'md'} else {newBp = 'lg'}if (this.curBp !== newBp) {this.curBp = newBp// 使用状态变量记录当前断点值AppStorage.setOrCreate('currentBreakpoint', this.curBp)}}onWindowStageCreate(windowStage: window.WindowStage) :void{windowStage.getMainWindow().then((windowObj) => {this.windowObj = windowObj// 获取应用启动时的窗口尺寸this.updateBreakpoint(windowObj.getWindowProperties().windowRect.width)// 注册回调函数,监听窗口尺寸变化windowObj.on('windowSizeChange', (windowSize)=>{this.updateBreakpoint(windowSize.width)})});// ...}//...
}
  1. 在页面中,获取及使用当前的断点。
@Entry
@Component
struct Index {@StorageProp('currentBreakpoint') curBp: string = 'sm'build() {Flex({justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center}) {Text(this.curBp).fontSize(50).fontWeight(FontWeight.Medium)}.width('100%').height('100%')}
}
  1. 运行及验证效果。

媒体查询

在实际应用开发过程中,开发者常常需要针对不同类型设备或同一类型设备的不同状态来修改应用的样式。媒体查询提供了丰富的媒体特征监听能力,可以监听应用显示区域变化、横竖屏、深浅色、设备类型等等,因此在应用开发过程中使用的非常广泛。

本小节仅介绍媒体查询跟断点的结合,即如何借助媒体查询能力,监听断点的变化,读者可以自行查阅官网中关于 媒体查询 的相关介绍了解更详细的用法。

说明: 类Web开发范式,支持在js文件和css文件中使用媒体查询,请查看 js媒体查询 了解详细用法。

示例:

通过媒体查询,监听应用窗口宽度变化,获取当前应用所处的断点值。

1.对通过媒体查询监听断点的功能做简单的封装,方便后续使用

// common/breakpointsystem.ets
import mediaQuery from '@ohos.mediaquery'declare interface BreakPointTypeOption<T> {xs?: Tsm?: Tmd?: Tlg?: Txl?: Txxl?: T
}export class BreakPointType<T> {options: BreakPointTypeOption<T>constructor(option: BreakPointTypeOption<T>) {this.options = option}getValue(currentBreakPoint: string) {if (currentBreakPoint === 'xs') {return this.options.xs} else if (currentBreakPoint === 'sm') {return this.options.sm} else if (currentBreakPoint === 'md') {return this.options.md} else if (currentBreakPoint === 'lg') {return this.options.lg} else if (currentBreakPoint === 'xl') {return this.options.xl} else if (currentBreakPoint === 'xxl') {return this.options.xxl} else {return undefined}}
}interface Breakpoint {name: stringsize: numbermediaQueryListener?: mediaQuery.MediaQueryListener
}export class BreakpointSystem {private currentBreakpoint: string = 'md'private breakpoints: Breakpoint[] = [{ name: 'xs', size: 0 }, { name: 'sm', size: 320 },{ name: 'md', size: 600 }, { name: 'lg', size: 840 }]private updateCurrentBreakpoint(breakpoint: string) {if (this.currentBreakpoint !== breakpoint) {this.currentBreakpoint = breakpointAppStorage.Set<string>('currentBreakpoint', this.currentBreakpoint)console.log('on current breakpoint: ' + this.currentBreakpoint)}}public register() {this.breakpoints.forEach((breakpoint: Breakpoint, index) => {let condition:stringif (index === this.breakpoints.length - 1) {condition = '(' + breakpoint.size + 'vp<=width' + ')'} else {condition = '(' + breakpoint.size + 'vp<=width<' + this.breakpoints[index + 1].size + 'vp)'}console.log(condition)breakpoint.mediaQueryListener = mediaQuery.matchMediaSync(condition)breakpoint.mediaQueryListener.on('change', (mediaQueryResult) => {if (mediaQueryResult.matches) {this.updateCurrentBreakpoint(breakpoint.name)}})})}public unregister() {this.breakpoints.forEach((breakpoint: Breakpoint) => {if(breakpoint.mediaQueryListener){breakpoint.mediaQueryListener.off('change')}})}
}

2.在页面中,通过媒体查询,监听应用窗口宽度变化,获取当前应用所处的断点值

// MediaQuerySample.ets
import { BreakpointSystem, BreakPointType } from 'common/breakpointsystem'@Entry
@Component
struct MediaQuerySample {@StorageLink('currentBreakpoint') private currentBreakpoint: string = "md";@State private icon: Resource = $r('app.media.md')private breakpointSystem: BreakpointSystem = new BreakpointSystem()aboutToAppear() {this.breakpointSystem.register()}aboutToDisappear() {this.breakpointSystem.unregister()}build() {Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {Image(new BreakPointType({sm:$r('app.media.sm'), md:$r('app.media.md'), lg:$r('app.media.lg')}).getValue(this.currentBreakpoint)!).height(100).width(100).objectFit(ImageFit.Contain)Text(this.currentBreakpoint).fontSize(24).margin(10)}.width('100%').height('100%')}
}

栅格布局

简介

栅格是多设备场景下通用的辅助定位工具,通过将空间分割为有规律的栅格。栅格可以显著降低适配不同屏幕尺寸的设计及开发成本,使得整体设计和开发流程更有秩序和节奏感,同时也保证多设备上应用显示的协调性和一致性,提升用户体验。

栅格的样式由Margin、Gutter、Columns三个属性决定。

  • Margin是相对应用窗口、父容器的左右边缘的距离,决定了内容可展示的整体宽度。

  • Gutter是相邻的两个Column之间的距离,决定内容间的紧密程度。

  • Columns是栅格中的列数,其数值决定了内容的布局复杂度。

单个Column的宽度是系统结合Margin、Gutter和Columns自动计算的,不需要也不允许开发者手动配置。

栅格布局就是栅格结合了断点,实现栅格布局能力的组件叫栅格组件。在实际使用场景中,可以根据需要配置不同断点下栅格组件中元素占据的列数,同时也可以调整Margin、Gutter、Columns的取值,从而实现不同的布局效果。

说明:

  • ArkUI在API 9对栅格组件做了重构,推出了新的栅格组件 GridRow ,同时原有的 GridContainer组件 及 栅格设置 已经废弃。
  • 本文中提到的栅格组件,如无特别说明,都是指GridRow和GridCol组件。

栅格组件的断点

栅格组件提供了丰富的断点定制能力。

(一)开发者可以修改断点的取值范围,支持启用最多6个断点。

  • 基于本文断点小节介绍的推荐值,栅格组件默认提供xs、sm、md、lg四个断点。

  • 栅格组件支持开发者修改断点的取值范围,除了默认的四个断点,还支持开发者启用xl和xxl两个额外的断点。

说明: 断点并非越多越好,通常每个断点都需要开发者“精心适配”以达到最佳显示效果。

示例1:

修改默认的断点范围,同时启用xl和xxl断点。

图片右下角显示了当前设备屏幕的尺寸(即应用窗口尺寸),可以看到随着窗口尺寸发生变化,栅格的断点也相应发生了改变。(为了便于理解,下图中将设备的DPI设置为160,此时1vp=1px)

@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:

以栅格组件宽度为参考物响应断点变化。满足窗口尺寸不变,而部分内容区需要做响应式变化的场景。

为了便于理解,下图中自定义预览器的设备屏幕宽度设置为650vp。示例代码中将侧边栏的变化范围控制在[100vp, 600vp],那么右侧的栅格组件宽度相对应在[550vp, 50vp]之间变化。根据代码中对栅格断点的配置,栅格组件宽度发生变化时,其断点相应的发生改变。

@Entry
@Component
struct GridRowSample2 {@State private currentBreakpoint: string = 'unknown';build() {// 用户可以通过拖拽侧边栏组件中的分隔线,调整侧边栏和内容区的宽度。SideBarContainer(SideBarContainerType.Embed){// 侧边栏,尺寸变化范围 [100vp, 600vp]Column(){}.width('100%').backgroundColor('#19000000')// 内容区,尺寸变化范围 [550vp, 50vp]GridRow({breakpoints: {value: ['100vp', '200vp', '300vp', '400vp', '500vp'],reference: BreakpointsReference.ComponentSize}}) {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;}).width('100%')}// 侧边栏拖拽到最小宽度时,不自动隐藏.autoHide(false).sideBarWidth(100)// 侧边栏的最小宽度.minSideBarWidth(100)// 侧边栏的最大宽度.maxSideBarWidth(600)}
}

(三)栅格组件的断点发生变化时,会通过onBreakPointChange事件通知开发者。

在之前的两个例子中,已经演示了onBreakpointChange事件的用法,此处不再赘述。

栅格组件的columns、gutter和margin

栅格组件columns默认为12列,gutter默认为0,同时支持开发者根据实际需要定义不同断点下的columns数量以及gutter长度。特别的,在栅格组件实际使用过程中,常常会发生多个元素占据的列数相加超过总列数而折行的场景。栅格组件还允许开发者分别定义水平方向的gutter(相邻两列之间的间距)和垂直方向的gutter(折行时相邻两行之间的间距)。

考虑到 组件通用属性 中已经有margin和padding,栅格组件不再单独提供额外的margin属性,直接使用通用属性即可。借助margin或者padding属性,均可以控制栅格组件与父容器左右边缘的距离,但是二者也存在一些差异:

  • margin区域在栅格组件的边界外,padding区域在栅格组件的边界内。

  • 栅格组件的backgroundColor会影响padding区域,但不会影响margin区域。

总的来讲,margin在组件外而padding在组件内,开发者可以根据实际需要进行选择及实现目标效果。

示例3:

不同断点下,定义不同的columns和gutter。

@Entry
@Component
struct GridRowSample3 {private bgColors: ResourceColor[] = [$r('sys.color.ohos_id_color_palette_aux1'),$r('sys.color.ohos_id_color_palette_aux2'),$r('sys.color.ohos_id_color_palette_aux3'),$r('sys.color.ohos_id_color_palette_aux4'),$r('sys.color.ohos_id_color_palette_aux5'),$r('sys.color.ohos_id_color_palette_aux6')]build() {// 配置不同断点下columns和gutter的取值GridRow({columns: {sm: 4, md: 8, lg: 12},gutter: {x: {sm: 8, md: 16, lg: 24}, y: {sm: 8, md: 16, lg: 24}}}) {ForEach(this.bgColors, (bgColor:ResourceColor)=>{GridCol({span: {sm: 2, md: 2, lg: 2}}) {Row().backgroundColor(bgColor).height(30).width('100%')}})}}
}

示例4:

通过通用属性margin或者padding,均可以控制栅格组件与其父容器左右两侧的距离,但padding区域计算在栅格组件内而margin区域计算在栅格组件外。此外,借助onBreakpointChange事件,还可以改变不同断点下margin或padding值。

@Entry
@Component
struct GridRowSample4 {@State private gridMargin: number = 0build() {Column() {Row().width('100%').height(30)// 使用padding控制栅格左右间距GridRow() {GridCol({span:{xs: 12, sm: 12, md: 12, lg:12}}) {Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {Text("padding").fontSize(24).fontWeight(FontWeight.Medium)}.backgroundColor('#19000000').width('100%')}}.height(50).borderWidth(2).borderColor('#F1CCB8').padding({left: this.gridMargin, right: this.gridMargin})// 借助断点变化事件配置不同断点下栅格组件的左右间距值.onBreakpointChange((currentBreakpoint: string) => {if (currentBreakpoint === 'lg' || currentBreakpoint === 'md') {this.gridMargin = 24} else {this.gridMargin = 12}})Row().width('100%').height(30)// 使用margin控制栅格左右间距GridRow() {GridCol({span:{xs: 12, sm: 12, md: 12, lg:12}}) {Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {Text("margin").fontSize(24).fontWeight(FontWeight.Medium)}.backgroundColor('#19000000').width('100%')}}.height(50).borderWidth(2).borderColor('#F1CCB8').margin({left: this.gridMargin, right: this.gridMargin})}}
}

栅格组件的span、offset和order

栅格组件(GridRow)的直接孩子节点只可以是栅格子组件(GridCol),GridCol组件支持配置span、offset和order三个参数。这三个参数的取值按照"xs -> sm -> md -> lg -> xl -> xxl"的向后方向具有继承性(不支持向前方向的继承性),例如将sm断点下span的值配置为3,不配置md断点下span的值,则md断点下span的取值也是3。

示例5:

通过span参数配置GridCol在不同断点下占据不同的列数。特别的,将md断点下和6的span配置为0,这样在md断点下3和6不会渲染和显示。

class Obj {public index: number = 1;public color: Resource = $r('sys.color.ohos_id_color_palette_aux1')
}
@Entry
@Component
struct GridRowSample6 {private elements: Obj[] = [{index: 1, color: $r('sys.color.ohos_id_color_palette_aux1')},{index: 2, color: $r('sys.color.ohos_id_color_palette_aux2')},{index: 3, color: $r('sys.color.ohos_id_color_palette_aux3')},{index: 4, color: $r('sys.color.ohos_id_color_palette_aux4')},{index: 5, color: $r('sys.color.ohos_id_color_palette_aux5')},{index: 6, color: $r('sys.color.ohos_id_color_palette_aux6')},]build() {GridRow() {ForEach(this.elements, (item:Obj)=>{GridCol({span: {sm: 6, md: 4, lg: 3}, offset: {sm: 0, md: 2, lg: 1} }) {Row() {Text('' + item.index).fontSize(24)}.justifyContent(FlexAlign.Center).backgroundColor(item.color).height(30).width('100%')}})}}
}

示例6:

通过offset参数,配置GridCol相对其前一个兄弟间隔的列数。

class Obj {public index: number = 1;public color: Resource = $r('sys.color.ohos_id_color_palette_aux1')
}
@Entry
@Component
struct GridRowSample7 {private elements: Obj[] = [{index: 1, color: $r('sys.color.ohos_id_color_palette_aux1')},{index: 2, color: $r('sys.color.ohos_id_color_palette_aux2')},{index: 3, color: $r('sys.color.ohos_id_color_palette_aux3')},{index: 4, color: $r('sys.color.ohos_id_color_palette_aux4')},{index: 5, color: $r('sys.color.ohos_id_color_palette_aux5')},{index: 6, color: $r('sys.color.ohos_id_color_palette_aux6')},]build() {GridRow() {ForEach(this.elements, (item:Obj)=>{GridCol({span: {sm: 6, md: 4, lg: 3}, order: {lg: (6-item.index)}}) {Row() {Text('' + item.index).fontSize(24)}.justifyContent(FlexAlign.Center).backgroundColor(item.color).height(30).width('100%')}})}}
}

示例7:

通过order属性,控制GridCol的顺序。在sm和md断点下,按照1至6的顺序排列显示;在lg断点下,按照6至1的顺序排列显示。

class Obj {public index: number = 1;public color: Resource = $r('sys.color.ohos_id_color_palette_aux1')
}
@Entry
@Component
struct GridRowSample7 {private elements: Obj[] = [{index: 1, color: $r('sys.color.ohos_id_color_palette_aux1')},{index: 2, color: $r('sys.color.ohos_id_color_palette_aux2')},{index: 3, color: $r('sys.color.ohos_id_color_palette_aux3')},{index: 4, color: $r('sys.color.ohos_id_color_palette_aux4')},{index: 5, color: $r('sys.color.ohos_id_color_palette_aux5')},{index: 6, color: $r('sys.color.ohos_id_color_palette_aux6')},]build() {GridRow() {ForEach(this.elements, (item:Obj)=>{GridCol({span: {sm: 6, md: 4, lg: 3}, order: {lg: (6-item.index)}}) {Row() {Text('' + item.index).fontSize(24)}.justifyContent(FlexAlign.Center).backgroundColor(item.color).height(30).width('100%')}})}}
}

示例8:

仅配置sm和lg断点下span、offset和order参数的值,则md断点下这三个参数的取值与sm断点相同(按照“sm->md->lg”的向后方向继承)。

class Obj {public index: number = 1;public color: Resource = $r('sys.color.ohos_id_color_palette_aux1')
}
@Entry
@Component
struct GridRowSample8 {private elements: Obj[] = [{index: 1, color: $r('sys.color.ohos_id_color_palette_aux1')},{index: 2, color: $r('sys.color.ohos_id_color_palette_aux2')},{index: 3, color: $r('sys.color.ohos_id_color_palette_aux3')},{index: 4, color: $r('sys.color.ohos_id_color_palette_aux4')},{index: 5, color: $r('sys.color.ohos_id_color_palette_aux5')},{index: 6, color: $r('sys.color.ohos_id_color_palette_aux6')},]build() {GridRow() {ForEach(this.elements, (item:Obj)=>{// 不配置md断点下三个参数的值,则其取值与sm断点相同GridCol({span: {sm:4, lg: 3}, offset: {sm: 2, lg: 1},order: {sm: (6-item.index), lg: item.index}}) {Row() {Text('' + item.index).fontSize(24)}.justifyContent(FlexAlign.Center).backgroundColor(item.color).height(30).width('100%')}})}}
}

栅格组件的嵌套使用

栅格组件可以嵌套使用以满足复杂场景的需要。

示例9:

class Obj {public index: number = 1;public color: Resource = $r('sys.color.ohos_id_color_palette_aux1')
}
@Entry
@Component
struct GridRowSample9 {private elements: Obj[] = [{index: 1, color: $r('sys.color.ohos_id_color_palette_aux1')},{index: 2, color: $r('sys.color.ohos_id_color_palette_aux2')},{index: 3, color: $r('sys.color.ohos_id_color_palette_aux3')},{index: 4, color: $r('sys.color.ohos_id_color_palette_aux4')},{index: 5, color: $r('sys.color.ohos_id_color_palette_aux5')},{index: 6, color: $r('sys.color.ohos_id_color_palette_aux6')},]build() {GridRow() {GridCol({span: {sm: 12, md: 10, lg: 8}, offset: {sm: 0, md: 1, lg: 2}}) {GridRow() {ForEach(this.elements, (item:Obj)=>{GridCol({span: {sm: 6, md: 4, lg: 3}}) {Row() {Text('' + item.index).fontSize(24)}.justifyContent(FlexAlign.Center).backgroundColor(item.color).height(30).width('100%')}})}.backgroundColor('#19000000').height('100%')}}}
}

总结

如前所述,栅格组件提供了丰富的自定义能力,功能异常灵活和强大。只需要明确栅格在不同断点下的Columns、Margin、Gutter及span等参数,即可确定最终布局,无需关心具体的设备类型及设备状态(如横竖屏)等。栅格可以节约设计团队与开发团队的沟通成本,提升整体开发效率。

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/762824.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

农业四情监测系统的工作原理

农业四情监测系统的工作原理【TH-Q1】农业四情监测系统是一种应用现代科技手段&#xff0c;以实现对农田环境信息的实时监测和数据采集的系统。这一系统通过对农田的土壤、气象、病虫害以及作物生长状况等四个方面的实时监测&#xff0c;帮助农民和农业管理者更好地了解和掌握农…

网络: 传输层

功能: 将数据从发送到传给接收端 UDP 无连接状态: 知道对端的IP和端口号就直接进行传输, 不需要建立连接不可靠: 没有确认机制, 没有重传机制. 出错不会管面向数据包: 不能够灵活的控制读写数据的次数和数量 发送速度快: 立即发送 报文结构 TCP 面向连接可靠 校验和序列号(按…

测试框架到底是什么,如何定义?

测试框架的关键组件是什么&#xff1f; 测试执行引擎&#xff1a;协调测试的运行、管理序列和报告结果。 测试脚本存储库&#xff1a;存储将要执行的实际测试用例或脚本。 测试数据&#xff1a;测试执行所需的输入数据&#xff0c;可以是静态的、动态的或动态生成的。 存根和…

十四届蓝桥杯 冶炼金属(二分 / 公式)

二分代码1&#xff1a; #include<iostream> #include<cstdio> #include<cmath> using namespace std;int get(int a, int b){int l1;r1e91;while(l<r){int mid lr >>1;if(a / mid < b){r mid;}else l mid 1;}return l; } int main() {int n…

【机器学习】基于机器学习的分类算法对比实验

摘要 基于机器学习的分类算法对比实验 本论文旨在对常见的分类算法进行综合比较和评估&#xff0c;并探索它们在机器学习分类领域的应用。实验结果显示&#xff0c;随机森林模型在CIFAR-10数据集上的精确度为0.4654&#xff0c;CatBoost模型为0.4916&#xff0c;XGBoost模型为…

Obsidian+PicGo+Gitee搭建免费图床

之前使用PicGoGitee配合Typora&#xff0c;后来因为换电脑Typora管理笔记不方便&#xff0c;换到Obsidian笔记&#xff0c;此处记录重新搭建图床的坑与经验。 主要参考# picGogitee搭建Obsidian图床&#xff0c;实现高效写作&#xff01; 1 下载安装PicGo 下载链接https://mo…

u盘表格不小心删除怎么恢复数据,u盘误删的表格怎么找回

u盘表格不小心删除怎么恢复数据?当我们使用U盘存储重要数据时,不小心删除文件或者整个表格可能会导致数据的丢失。这种情况下,我们需要采取一些措施来恢复被删除的数据。u盘误删的表格怎么找回?幸运的是,有一些方法可以帮助我们恢复U盘中的数据,即使它们被删除了。在本文…

球面数据的几何深度学习--球形 CNN

目录 一、说明二、球形 CNN概述三、球面数据的对称性四、标准&#xff08;平面&#xff09;CNN的局限性五、卷积并发症六、球面卷积七、球面卷积是不够的 一、说明 球面数据的几何深度学习–球形 CNN。通过对物理世界的平移对称性进行编码&#xff0c;卷积神经网络 &#xff…

备战2024年中学生古诗文大会(初中组):单选题真题和独家解析

今天我们继续来做中学生古诗文大会&#xff08;初中组&#xff09;——简称初中生古诗文大会的一些真题&#xff0c;让大家了解初中生古诗文大会的考察内容和形式&#xff0c;并且提供了我独家的题目解析和答案&#xff0c;供初中的同学们学习和参考。 有一些朋友问中学生古诗…

软考机考新模式,有什么影响?

关于软考考试改机考的影响&#xff0c;初步预测可能会有以下几个影响&#xff1a; 1、需要掌握的基础知识要求更高 机考可能导致每个人的题目不同&#xff0c;因此需要更扎实地掌握基础知识&#xff0c;认真备考每个知识点&#xff0c;核心分值可能会全部打散&#xff0c;不能…

2024-3-21-Qtday2作业

要求&#xff1a; 自由发挥登录窗口的应用场景&#xff0c;实现一个登录窗口界面。&#xff08;不要使用课堂上的图片和代码&#xff0c;自己发挥&#xff0c;有利于后面项目的完成&#xff09; 要求&#xff1a; 1. 需要使用Ui界面文件进行界面设计 2. ui界面上的组件相关…

外腔激光器(ECL)市场发展空间大 外腔半导体激光器(ECDL)是主要产品类型

外腔激光器&#xff08;ECL&#xff09;市场发展空间大 外腔半导体激光器&#xff08;ECDL&#xff09;是主要产品类型 外腔激光器&#xff08;ECL&#xff09;&#xff0c;是一种利用外腔进行光反馈的激光器。根据新思界产业研究中心发布的《》2024-2029年中国外腔激光器&…

docker快速安装达梦数据库

docker快速安装达梦数据库 文章目录 docker快速安装达梦数据库前言环境准备下载镜像运行、配置容器 前言 因为公司需要将自己的底代码平台与客户的需求做适配&#xff0c;客户要求必须满足信创要求&#xff0c;使用达梦数据库。所以需要将原有的MySQL数据库与达梦数据库适配&a…

如何在 Odoo 17 的 齿轮菜单⚙️ 中添加新菜单

在 Odoo 中&#xff0c;齿轮菜单是一个重要组件&#xff0c;允许用户访问与系统内不同模型和功能相关的各种配置选项和设置。它通常由位于用户界面左上角的齿轮或齿轮图标表示。下图显示了 "sale.order "模型的齿轮菜单。 默认情况下&#xff0c;我们在 CogMenu 中提…

8 克隆虚拟机

后期集群我们需要使用多台服务器&#xff0c;此处我们先克隆三台&#xff0c;master,slave01,slave02. 1.先关闭模版虚拟机。再选择 模版虚拟机hadoop100右击--》管理 --》克隆 2.下图中特别注意&#xff1a;建议使用集群的名字作为虚拟机名称。目前克隆主机master. 以上步骤完…

京东云开发者:DDD 学习与感悟 —— 向屎山冲锋

原文地址:https://mp.weixin.qq.com/s/Hvq1ttBopbxypatVcKcLiA 软件系统是通过软件开发来解决某一个业务领域或问题单元而产生的一个交付物。而通过软件设计可以帮助我们开发出更加健壮的软件系统。因此&#xff0c;软件设计是从业务领域到软件开发之间的桥梁。而DDD是软件设计…

智慧公厕是干什么的?智慧公厕系统有哪些内容?

公共厕所一直是城市管理的难题&#xff0c;传统的管理方式无法解决诸多问题&#xff0c;如环境卫生不佳、查找厕位难、消耗品提供不及时、设施设备容易被破坏等。而随着科技的不断发展&#xff0c;智慧公厕系统应运而生&#xff0c;为公共厕所的管理带来全新的思路和解决方案。…

Swift知识点(二)

17. 字面量协议、模式匹配、条件编译 字面量&#xff08;Literal&#xff09; var age 10 var isRed false var name "Jack"上面代码中&#xff1a;10、false、"Jack"就是字面量 可以看到&#xff0c;初始化过程很简单&#xff0c;直接赋值即可 Swif…

AI应用开发-基于python的知识图谱技术

AI应用开发相关目录 本专栏包括AI应用开发相关内容分享&#xff0c;包括不限于AI算法部署实施细节、AI应用后端分析服务相关概念及开发技巧、AI应用后端应用服务相关概念及开发技巧、AI应用前端实现路径及开发技巧 适用于具备一定算法及Python使用基础的人群 AI应用开发流程概…

力扣爆刷第102天之hot100五连刷96-100

力扣爆刷第102天之hot100五连刷96-100 文章目录 力扣爆刷第102天之hot100五连刷96-100一、136. 只出现一次的数字二、169. 多数元素三、75. 颜色分类四、31. 下一个排列五、287. 寻找重复数 一、136. 只出现一次的数字 题目链接&#xff1a;https://leetcode.cn/problems/sing…