1e41f4b71Sopenharmony_ci# Navigation如何实现多场景UI适配 2e41f4b71Sopenharmony_ci## 场景介绍 3e41f4b71Sopenharmony_ci应用在不同屏幕大小的设备上运行时,往往有不同的UI适配,以聊天应用举例: 4e41f4b71Sopenharmony_ci* 在窄屏设备上,联系人和聊天区在多窗口中体现。 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_ci* 在宽屏设备上,联系人和聊天区在同一窗口体现。 7e41f4b71Sopenharmony_ci 8e41f4b71Sopenharmony_ci要做好适配,往往需要开发者开发多套代码,以便运行在不同设备上。但是这样耗时耗力,于是ArkUI针对这种场景提供了分栏组件,可以通过一套代码完成不同设别的适配,本例简单介绍下如何使用分栏组件实现上述场景。 9e41f4b71Sopenharmony_ci 10e41f4b71Sopenharmony_ci## 效果呈现 11e41f4b71Sopenharmony_ci效果图如下所示: 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ci窄屏设备效果图: 14e41f4b71Sopenharmony_ci 15e41f4b71Sopenharmony_ci 16e41f4b71Sopenharmony_ci 17e41f4b71Sopenharmony_ci宽屏设备效果图: 18e41f4b71Sopenharmony_ci 19e41f4b71Sopenharmony_ci 20e41f4b71Sopenharmony_ci## 运行环境 21e41f4b71Sopenharmony_ci本例基于以下环境开发,开发者也可以基于其它适配的版本进行开发: 22e41f4b71Sopenharmony_ci- IDE:DevEco Studio 3.1 Release 23e41f4b71Sopenharmony_ci- SDK: Ohos_sdk_public 3.2.12.5(API Version 9 Release) 24e41f4b71Sopenharmony_ci## 实现思路 25e41f4b71Sopenharmony_ci想要实现一多效果,所有的页面元素必须在Navigation的容器中展示,Navigation一般作为页面的根容器,包括单页面、分栏和自适应三种显示模式,可通过mode属性设置页面的显示模式。 26e41f4b71Sopenharmony_ci 27e41f4b71Sopenharmony_ci导航区中使用NavRouter子组件实现导航栏功能,内容页主要显示NavDestination子组件中的内容。 28e41f4b71Sopenharmony_ci 29e41f4b71Sopenharmony_ciNavRouter是和Navigation搭配使用的特殊子组件,默认提供点击响应处理,不需要开发者自定义点击事件逻辑。NavRouter有且仅有两个根节点,第二个根节点是NavDestination。NavDestination用于显示Navigation组件的内容页。当开发者点击NavRouter组件时,会跳转到对应的NavDestination内容区。 30e41f4b71Sopenharmony_ci 31e41f4b71Sopenharmony_ci 32e41f4b71Sopenharmony_ci本例涉及一些关键特性以及实现方法如下: 33e41f4b71Sopenharmony_ci- 创建Navigation组件,同时通过设置mode属性为auto来控制页面显示效果。 34e41f4b71Sopenharmony_ci- Navigation通过与NavRouter组件搭配使用,实现页面分栏效果。 35e41f4b71Sopenharmony_ci 36e41f4b71Sopenharmony_ci > NavRouter必须包含两个子组件,其子组件即为实现分栏效果的组件,其中第二个子组件必须为NavDestination(第一个即可理解为为导航栏,第二个组件可理解为内容区)。 37e41f4b71Sopenharmony_ci 38e41f4b71Sopenharmony_ci- 通过向父组件NavRouter添加子组件NavDestination,创建导航内容区并添加文本。 39e41f4b71Sopenharmony_ci- 内容区域的补充:根据应用的场景,添加TextArea组件完善内容区。 40e41f4b71Sopenharmony_ci 41e41f4b71Sopenharmony_ci 42e41f4b71Sopenharmony_ci## 开发步骤 43e41f4b71Sopenharmony_ci1. 创建Navigation组件,同时通过设置mode属性为auto来控制页面显示(自适应模式下,当设备宽度大于520vp时,Navigation组件采用分栏模式,反之采用单页面模式)。 44e41f4b71Sopenharmony_ci具体代码如下: 45e41f4b71Sopenharmony_ci ```ts 46e41f4b71Sopenharmony_ci build() { 47e41f4b71Sopenharmony_ci Column() { 48e41f4b71Sopenharmony_ci Navigation() { 49e41f4b71Sopenharmony_ci ... 50e41f4b71Sopenharmony_ci } 51e41f4b71Sopenharmony_ci // Navigation组件mode属性设置为auto。自适应模式下,当设备宽度大于520vp时,Navigation组件采用分栏模式,反之采用单页面模式。 52e41f4b71Sopenharmony_ci .mode(NavigationMode.Auto) 53e41f4b71Sopenharmony_ci } 54e41f4b71Sopenharmony_ci .height('100%') 55e41f4b71Sopenharmony_ci } 56e41f4b71Sopenharmony_ci ``` 57e41f4b71Sopenharmony_ci2. 通过NavRouter组件创建导航栏:Navigation通过与NavRouter组件搭配实现页面分栏效果。 58e41f4b71Sopenharmony_ci * 自定义导航栏NavigationTitle。 59e41f4b71Sopenharmony_ci * 添加Navigation子组件NavRoute,创建导航栏。 60e41f4b71Sopenharmony_ci * 通过ForEach循环渲染导航栏内容,且导航栏内容通过List组件显示。 61e41f4b71Sopenharmony_ci 具体代码如下: 62e41f4b71Sopenharmony_ci ```ts 63e41f4b71Sopenharmony_ci // 自定义导航栏title 64e41f4b71Sopenharmony_ci @Builder NavigationTitle(index) { 65e41f4b71Sopenharmony_ci Column() { 66e41f4b71Sopenharmony_ci Row() { 67e41f4b71Sopenharmony_ci Text('互动交流' + index + '群') 68e41f4b71Sopenharmony_ci .fontColor('#182431') 69e41f4b71Sopenharmony_ci .fontSize(20) 70e41f4b71Sopenharmony_ci } 71e41f4b71Sopenharmony_ci } 72e41f4b71Sopenharmony_ci .width($r("app.float.titHeightFloat")) 73e41f4b71Sopenharmony_ci } 74e41f4b71Sopenharmony_ci 75e41f4b71Sopenharmony_ci build() { 76e41f4b71Sopenharmony_ci Column() { 77e41f4b71Sopenharmony_ci Navigation() { 78e41f4b71Sopenharmony_ci Text('联系人(' + this.arr.length + ')') 79e41f4b71Sopenharmony_ci .fontWeight(500) 80e41f4b71Sopenharmony_ci .margin({ top: 10, right: 10, left: 19 }) 81e41f4b71Sopenharmony_ci .fontSize(17) 82e41f4b71Sopenharmony_ci 83e41f4b71Sopenharmony_ci List({ initialIndex: 0 }) { 84e41f4b71Sopenharmony_ci // 通过ForEach循环渲染导航栏内容 85e41f4b71Sopenharmony_ci ForEach(this.arr, (item: number, index: number) => { 86e41f4b71Sopenharmony_ci ListItem() { 87e41f4b71Sopenharmony_ci // 导航组件,默认提供点击响应处理 88e41f4b71Sopenharmony_ci NavRouter() { 89e41f4b71Sopenharmony_ci // 导航区内容 90e41f4b71Sopenharmony_ci Column() { 91e41f4b71Sopenharmony_ci Row() { 92e41f4b71Sopenharmony_ci Image($r('app.media.icon1')) 93e41f4b71Sopenharmony_ci .width(35) 94e41f4b71Sopenharmony_ci .height(35) 95e41f4b71Sopenharmony_ci .borderRadius(35) 96e41f4b71Sopenharmony_ci .margin({ left: 3, right: 10 }) 97e41f4b71Sopenharmony_ci Text('互动交流' + item + '群') 98e41f4b71Sopenharmony_ci .fontSize(22) 99e41f4b71Sopenharmony_ci .textAlign(TextAlign.Center) 100e41f4b71Sopenharmony_ci } 101e41f4b71Sopenharmony_ci .padding({ left: 10 }) 102e41f4b71Sopenharmony_ci .width('100%') 103e41f4b71Sopenharmony_ci .height(80) 104e41f4b71Sopenharmony_ci .backgroundColor(this.dex == index ? '#eee' : '#fff') 105e41f4b71Sopenharmony_ci 106e41f4b71Sopenharmony_ci Divider().strokeWidth(1).color('#F1F3F5') 107e41f4b71Sopenharmony_ci }.width('100%') 108e41f4b71Sopenharmony_ci 109e41f4b71Sopenharmony_ci ... 110e41f4b71Sopenharmony_ci 111e41f4b71Sopenharmony_ci } 112e41f4b71Sopenharmony_ci .width('100%') 113e41f4b71Sopenharmony_ci } 114e41f4b71Sopenharmony_ci }, item => item) 115e41f4b71Sopenharmony_ci } 116e41f4b71Sopenharmony_ci .height('100%').margin({ top: 12 }) 117e41f4b71Sopenharmony_ci } 118e41f4b71Sopenharmony_ci // Navigation组件默认为自适应模式,此时mode属性为NavigationMode.Auto。自适应模式下,当设备宽度大于520vp时,Navigation组件采用分栏模式,反之采用单页面模式。 119e41f4b71Sopenharmony_ci .mode(NavigationMode.Auto) 120e41f4b71Sopenharmony_ci .hideTitleBar(true) 121e41f4b71Sopenharmony_ci .hideToolBar(true) 122e41f4b71Sopenharmony_ci } 123e41f4b71Sopenharmony_ci .height('100%') 124e41f4b71Sopenharmony_ci } 125e41f4b71Sopenharmony_ci ``` 126e41f4b71Sopenharmony_ci 127e41f4b71Sopenharmony_ci3. 通过添加组件NavDestination,创建内容栏并添加文本。 128e41f4b71Sopenharmony_ci NavRouter包含两个子组件,其子组件即为实现分栏效果的组件,其中第二个子组件必须为NavDestination,用于显示导航内容区(第一个即可理解为为导航栏,第二个组件可理解为内容区); 129e41f4b71Sopenharmony_ci 内容区部分代码: 130e41f4b71Sopenharmony_ci 131e41f4b71Sopenharmony_ci ```ts 132e41f4b71Sopenharmony_ci build() { 133e41f4b71Sopenharmony_ci Column() { 134e41f4b71Sopenharmony_ci Navigation() { 135e41f4b71Sopenharmony_ci ... 136e41f4b71Sopenharmony_ci 137e41f4b71Sopenharmony_ci // 导航组件,默认提供点击响应处理 138e41f4b71Sopenharmony_ci NavRouter() { 139e41f4b71Sopenharmony_ci // 导航区内容 140e41f4b71Sopenharmony_ci ... 141e41f4b71Sopenharmony_ci 142e41f4b71Sopenharmony_ci // NavRouter组件的子组件,用于显示导航内容区。 143e41f4b71Sopenharmony_ci NavDestination() { 144e41f4b71Sopenharmony_ci // 内容区 145e41f4b71Sopenharmony_ci ForEach([0, 1], (item: number) => { 146e41f4b71Sopenharmony_ci Flex({ direction: FlexDirection.Row }) { 147e41f4b71Sopenharmony_ci Row() { 148e41f4b71Sopenharmony_ci Image($r('app.media.icon2')) 149e41f4b71Sopenharmony_ci .width(40) 150e41f4b71Sopenharmony_ci .height(40) 151e41f4b71Sopenharmony_ci .borderRadius(40) 152e41f4b71Sopenharmony_ci .margin({ right: 15 }) 153e41f4b71Sopenharmony_ci Text('今天幸运数字' + index.toString()) 154e41f4b71Sopenharmony_ci .fontSize(20) 155e41f4b71Sopenharmony_ci .height(40) 156e41f4b71Sopenharmony_ci .backgroundColor('#f1f9ff') 157e41f4b71Sopenharmony_ci .borderRadius(10) 158e41f4b71Sopenharmony_ci .padding(10) 159e41f4b71Sopenharmony_ci } 160e41f4b71Sopenharmony_ci .padding({ left: 15 }) 161e41f4b71Sopenharmony_ci .margin({ top: 15 }) 162e41f4b71Sopenharmony_ci } 163e41f4b71Sopenharmony_ci }, item => item) 164e41f4b71Sopenharmony_ci .... 165e41f4b71Sopenharmony_ci } 166e41f4b71Sopenharmony_ci 167e41f4b71Sopenharmony_ci // 设置内容区标题 168e41f4b71Sopenharmony_ci .title(this.NavigationTitle(index)) 169e41f4b71Sopenharmony_ci } 170e41f4b71Sopenharmony_ci } 171e41f4b71Sopenharmony_ci // Navigation组件默认为自适应模式,此时mode属性为NavigationMode.Auto。自适应模式下,当设备宽度大于520vp时,Navigation组件采用分栏模式,反之采用单页面模式。 172e41f4b71Sopenharmony_ci .mode(NavigationMode.Auto) 173e41f4b71Sopenharmony_ci .hideTitleBar(true) 174e41f4b71Sopenharmony_ci .hideToolBar(true) 175e41f4b71Sopenharmony_ci } 176e41f4b71Sopenharmony_ci .height('100%') 177e41f4b71Sopenharmony_ci } 178e41f4b71Sopenharmony_ci ``` 179e41f4b71Sopenharmony_ci 180e41f4b71Sopenharmony_ci 181e41f4b71Sopenharmony_ci4. 内容区域的补充:完善内容区域文本组件。 182e41f4b71Sopenharmony_ci具体代码块如下: 183e41f4b71Sopenharmony_ci 184e41f4b71Sopenharmony_ci ```ts 185e41f4b71Sopenharmony_ci ... 186e41f4b71Sopenharmony_ci Column() { 187e41f4b71Sopenharmony_ci TextArea({ 188e41f4b71Sopenharmony_ci placeholder: '请输入文字', 189e41f4b71Sopenharmony_ci }) 190e41f4b71Sopenharmony_ci .placeholderFont({ size: 16, weight: 400 }) 191e41f4b71Sopenharmony_ci .width('100%') 192e41f4b71Sopenharmony_ci .height($r("app.float.heightFloat")) 193e41f4b71Sopenharmony_ci .fontSize(16) 194e41f4b71Sopenharmony_ci .fontColor('#182431') 195e41f4b71Sopenharmony_ci .backgroundColor('#FFFFFF') 196e41f4b71Sopenharmony_ci .borderRadius(0) 197e41f4b71Sopenharmony_ci } 198e41f4b71Sopenharmony_ci .margin({ top: $r("app.float.marHeightFloat") }) 199e41f4b71Sopenharmony_ci .height($r("app.float.ColHeightFloat")) 200e41f4b71Sopenharmony_ci .justifyContent(FlexAlign.End) 201e41f4b71Sopenharmony_ci ... 202e41f4b71Sopenharmony_ci ``` 203e41f4b71Sopenharmony_ci 204e41f4b71Sopenharmony_ci## 完整代码 205e41f4b71Sopenharmony_ci示例完整代码如下: 206e41f4b71Sopenharmony_ci 207e41f4b71Sopenharmony_ci```ts 208e41f4b71Sopenharmony_ci@Entry 209e41f4b71Sopenharmony_ci@Component 210e41f4b71Sopenharmony_cistruct NavigationExample { 211e41f4b71Sopenharmony_ci @State arr: number[] = [0, 1, 2, 3, 4, 5] 212e41f4b71Sopenharmony_ci @State dex: number = 0 213e41f4b71Sopenharmony_ci 214e41f4b71Sopenharmony_ci @Builder NavigationTitle(index) { 215e41f4b71Sopenharmony_ci Column() { 216e41f4b71Sopenharmony_ci Row() { 217e41f4b71Sopenharmony_ci Text('互动交流' + index + '群') 218e41f4b71Sopenharmony_ci .fontColor('#182431') 219e41f4b71Sopenharmony_ci .fontSize(20) 220e41f4b71Sopenharmony_ci } 221e41f4b71Sopenharmony_ci } 222e41f4b71Sopenharmony_ci .width($r("app.float.titHeightFloat")) 223e41f4b71Sopenharmony_ci } 224e41f4b71Sopenharmony_ci 225e41f4b71Sopenharmony_ci build() { 226e41f4b71Sopenharmony_ci Column() { 227e41f4b71Sopenharmony_ci Navigation() { 228e41f4b71Sopenharmony_ci Text('联系人(' + this.arr.length + ')') 229e41f4b71Sopenharmony_ci .fontWeight(500) 230e41f4b71Sopenharmony_ci .margin({ top: 10, right: 10, left: 19 }) 231e41f4b71Sopenharmony_ci .fontSize(17) 232e41f4b71Sopenharmony_ci List({ initialIndex: 0 }) { 233e41f4b71Sopenharmony_ci // 通过ForEach循环渲染导航栏内容 234e41f4b71Sopenharmony_ci ForEach(this.arr, (item: number, index: number) => { 235e41f4b71Sopenharmony_ci ListItem() { 236e41f4b71Sopenharmony_ci // 导航组件,默认提供点击响应处理 237e41f4b71Sopenharmony_ci NavRouter() { 238e41f4b71Sopenharmony_ci // 导航区内容 239e41f4b71Sopenharmony_ci Column() { 240e41f4b71Sopenharmony_ci Row() { 241e41f4b71Sopenharmony_ci Image($r('app.media.icon1')) 242e41f4b71Sopenharmony_ci .width(35) 243e41f4b71Sopenharmony_ci .height(35) 244e41f4b71Sopenharmony_ci .borderRadius(35) 245e41f4b71Sopenharmony_ci .margin({ left: 3, right: 10 }) 246e41f4b71Sopenharmony_ci Text('互动交流' + item + '群') 247e41f4b71Sopenharmony_ci .fontSize(22) 248e41f4b71Sopenharmony_ci .textAlign(TextAlign.Center) 249e41f4b71Sopenharmony_ci } 250e41f4b71Sopenharmony_ci .padding({ left: 10 }) 251e41f4b71Sopenharmony_ci .width('100%') 252e41f4b71Sopenharmony_ci .height(80) 253e41f4b71Sopenharmony_ci .backgroundColor(this.dex == index ? '#eee' : '#fff') 254e41f4b71Sopenharmony_ci 255e41f4b71Sopenharmony_ci Divider().strokeWidth(1).color('#F1F3F5') 256e41f4b71Sopenharmony_ci }.width('100%') 257e41f4b71Sopenharmony_ci 258e41f4b71Sopenharmony_ci // NavRouter组件的子组件,用于显示导航内容区。 259e41f4b71Sopenharmony_ci NavDestination() { 260e41f4b71Sopenharmony_ci ForEach([0, 1], (item: number) => { 261e41f4b71Sopenharmony_ci Flex({ direction: FlexDirection.Row }) { 262e41f4b71Sopenharmony_ci Row() { 263e41f4b71Sopenharmony_ci Image($r('app.media.icon2')) 264e41f4b71Sopenharmony_ci .width(40) 265e41f4b71Sopenharmony_ci .height(40) 266e41f4b71Sopenharmony_ci .borderRadius(40) 267e41f4b71Sopenharmony_ci .margin({ right: 15 }) 268e41f4b71Sopenharmony_ci Text('今天幸运数字' + index.toString()) 269e41f4b71Sopenharmony_ci .fontSize(20) 270e41f4b71Sopenharmony_ci .height(40) 271e41f4b71Sopenharmony_ci .backgroundColor('#f1f9ff') 272e41f4b71Sopenharmony_ci .borderRadius(10) 273e41f4b71Sopenharmony_ci .padding(10) 274e41f4b71Sopenharmony_ci } 275e41f4b71Sopenharmony_ci .padding({ left: 15 }) 276e41f4b71Sopenharmony_ci .margin({ top: 15 }) 277e41f4b71Sopenharmony_ci } 278e41f4b71Sopenharmony_ci }, item => item) 279e41f4b71Sopenharmony_ci 280e41f4b71Sopenharmony_ci Row() { 281e41f4b71Sopenharmony_ci Text('幸运数字' + item.toString()) 282e41f4b71Sopenharmony_ci .fontSize(20) 283e41f4b71Sopenharmony_ci .margin({ right: 10 }) 284e41f4b71Sopenharmony_ci .height(40) 285e41f4b71Sopenharmony_ci .backgroundColor('#68c059') 286e41f4b71Sopenharmony_ci .borderRadius(10) 287e41f4b71Sopenharmony_ci .padding(10) 288e41f4b71Sopenharmony_ci Image($r('app.media.icon3')) 289e41f4b71Sopenharmony_ci .width(40) 290e41f4b71Sopenharmony_ci .height(40) 291e41f4b71Sopenharmony_ci .borderRadius(40) 292e41f4b71Sopenharmony_ci .margin({ right: 15 }) 293e41f4b71Sopenharmony_ci } 294e41f4b71Sopenharmony_ci .padding({ left: 15 }) 295e41f4b71Sopenharmony_ci .margin({ top: 150 }) 296e41f4b71Sopenharmony_ci .width('100%') 297e41f4b71Sopenharmony_ci .direction(Direction.Rtl) 298e41f4b71Sopenharmony_ci 299e41f4b71Sopenharmony_ci Column() { 300e41f4b71Sopenharmony_ci TextArea({placeholder: '请输入文字',}) 301e41f4b71Sopenharmony_ci .placeholderFont({ size: 16, weight: 400 }) 302e41f4b71Sopenharmony_ci .width('100%') 303e41f4b71Sopenharmony_ci .height($r("app.float.heightFloat")) 304e41f4b71Sopenharmony_ci .fontSize(16) 305e41f4b71Sopenharmony_ci .fontColor('#182431') 306e41f4b71Sopenharmony_ci .backgroundColor('#FFFFFF') 307e41f4b71Sopenharmony_ci .borderRadius(0) 308e41f4b71Sopenharmony_ci } 309e41f4b71Sopenharmony_ci .margin({ top: $r("app.float.marHeightFloat") }) 310e41f4b71Sopenharmony_ci .height($r("app.float.ColHeightFloat")) 311e41f4b71Sopenharmony_ci .justifyContent(FlexAlign.End) 312e41f4b71Sopenharmony_ci } 313e41f4b71Sopenharmony_ci .backgroundColor('#eee') 314e41f4b71Sopenharmony_ci // 设置内容区标题 315e41f4b71Sopenharmony_ci .title(this.NavigationTitle(index)) 316e41f4b71Sopenharmony_ci } 317e41f4b71Sopenharmony_ci .width('100%') 318e41f4b71Sopenharmony_ci } 319e41f4b71Sopenharmony_ci }, item => item) 320e41f4b71Sopenharmony_ci } 321e41f4b71Sopenharmony_ci .height('100%').margin({ top: 12 }) 322e41f4b71Sopenharmony_ci } 323e41f4b71Sopenharmony_ci // Navigation组件mode属性设置为auto。自适应模式下,当设备宽度大于520vp时,Navigation组件采用分栏模式,反之采用单页面模式。 324e41f4b71Sopenharmony_ci .mode(NavigationMode.Auto) 325e41f4b71Sopenharmony_ci .hideTitleBar(true) 326e41f4b71Sopenharmony_ci .hideToolBar(true) 327e41f4b71Sopenharmony_ci } 328e41f4b71Sopenharmony_ci .height('100%') 329e41f4b71Sopenharmony_ci } 330e41f4b71Sopenharmony_ci} 331e41f4b71Sopenharmony_ci``` 332e41f4b71Sopenharmony_ci## 参考 333e41f4b71Sopenharmony_ci[List组件](../application-dev/reference/apis-arkui/arkui-ts/ts-container-list.md) 334e41f4b71Sopenharmony_ci 335e41f4b71Sopenharmony_ci[Flex组件](../application-dev/reference/apis-arkui/arkui-ts/ts-container-flex.md) 336e41f4b71Sopenharmony_ci 337e41f4b71Sopenharmony_ci[Navigation](../application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md) 338e41f4b71Sopenharmony_ci 339e41f4b71Sopenharmony_ci[NavRouter](../application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-navrouter.md) 340e41f4b71Sopenharmony_ci 341e41f4b71Sopenharmony_ci[NavDestination](../application-dev/reference/apis-arkui/arkui-ts/ts-basic-components-navdestination.md) 342e41f4b71Sopenharmony_ci 343