鸿蒙(HarmonyOS)Navigation如何实现多场景UI适配?

news2024/11/17 16:17:28

场景介绍

应用在不同屏幕大小的设备上运行时,往往有不同的UI适配,以聊天应用举例:

  • 在窄屏设备上,联系人和聊天区在多窗口中体现。
  • 在宽屏设备上,联系人和聊天区在同一窗口体现。

要做好适配,往往需要开发者开发多套代码,以便运行在不同设备上。但是这样耗时耗力,于是ArkUI针对这种场景提供了分栏组件,可以通过一套代码完成不同设别的适配,本例简单介绍下如何使用分栏组件实现上述场景。

效果呈现

效果图如下所示:

窄屏设备效果图:

宽屏设备效果图:

运行环境

本例基于以下环境开发,开发者也可以基于其它适配的版本进行开发: - IDE:DevEco Studio 3.1 Release - SDK: Ohos_sdk_public 3.2.12.5(API Version 9 Release)

实现思路

想要实现一多效果,所有的页面元素必须在Navigation的容器中展示,Navigation一般作为页面的根容器,包括单页面、分栏和自适应三种显示模式,可通过mode属性设置页面的显示模式。

导航区中使用NavRouter子组件实现导航栏功能,内容页主要显示NavDestination子组件中的内容。

NavRouter是和Navigation搭配使用的特殊子组件,默认提供点击响应处理,不需要开发者自定义点击事件逻辑。NavRouter有且仅有两个根节点,第二个根节点是NavDestination。NavDestination用于显示Navigation组件的内容页。当开发者点击NavRouter组件时,会跳转到对应的NavDestination内容区。

本例涉及一些关键特性以及实现方法如下: - 创建Navigation组件,同时通过设置mode属性为auto来控制页面显示效果。 - Navigation通过与NavRouter组件搭配使用,实现页面分栏效果。

NavRouter必须包含两个子组件,其子组件即为实现分栏效果的组件,其中第二个子组件必须为NavDestination(第一个即可理解为为导航栏,第二个组件可理解为内容区)。

  • 通过向父组件NavRouter添加子组件NavDestination,创建导航内容区并添加文本。
  • 内容区域的补充:根据应用的场景,添加TextArea组件完善内容区。

开发步骤

  1. 创建Navigation组件,同时通过设置mode属性为auto来控制页面显示(自适应模式下,当设备宽度大于520vp时,Navigation组件采用分栏模式,反之采用单页面模式)。 具体代码如下: ts build() { Column() { Navigation() { ... } // Navigation组件mode属性设置为auto。自适应模式下,当设备宽度大于520vp时,Navigation组件采用分栏模式,反之采用单页面模式。 .mode(NavigationMode.Auto) } .height('100%') }

  2. 通过NavRouter组件创建导航栏:Navigation通过与NavRouter组件搭配实现页面分栏效果。

    • 自定义导航栏NavigationTitle。

    • 添加Navigation子组件NavRoute,创建导航栏。

    • 通过ForEach循环渲染导航栏内容,且导航栏内容通过List组件显示。 具体代码如下:

      // 自定义导航栏title
      @Builder NavigationTitle(index) {
          Column() {
              Row() {
                  Text('互动交流' + index + '群')
                  .fontColor('#182431')
                  .fontSize(20)
                  }
              }
          .width($r("app.float.titHeightFloat"))
      }

      build() {
          Column() {
              Navigation() {
                  Text('联系人(' + this.arr.length + ')')
                  .fontWeight(500)
                  .margin({ top: 10, right: 10, left: 19 })
                  .fontSize(17)

                  List({ initialIndex: 0 }) {
                      // 通过ForEach循环渲染导航栏内容
                      ForEach(this.arr, (item: number, index: number) => {
                          ListItem() {
                              // 导航组件,默认提供点击响应处理
                              NavRouter() {
                                  // 导航区内容
                                  Column() {
                                      Row() {
                                          Image($r('app.media.icon1'))
                                              .width(35)
                                              .height(35)
                                              .borderRadius(35)
                                              .margin({ left: 3, right: 10 })
                                          Text('互动交流' + item + '群')
                                              .fontSize(22)
                                              .textAlign(TextAlign.Center)
                                      }
                                      .padding({ left: 10 })
                                      .width('100%')
                                      .height(80)
                                      .backgroundColor(this.dex == index ? '#eee' : '#fff')

                                      Divider().strokeWidth(1).color('#F1F3F5')
                                  }.width('100%')

                                  ...

                              }
                              .width('100%')
                          }
                      }, item => item)
                  }
                  .height('100%').margin({ top: 12 })
              }
              //  Navigation组件默认为自适应模式,此时mode属性为NavigationMode.Auto。自适应模式下,当设备宽度大于520vp时,Navigation组件采用分栏模式,反之采用单页面模式。
              .mode(NavigationMode.Auto)
              .hideTitleBar(true)
              .hideToolBar(true)
          }
          .height('100%')
      }
  1. 通过添加组件NavDestination,创建内容栏并添加文本。 NavRouter包含两个子组件,其子组件即为实现分栏效果的组件,其中第二个子组件必须为NavDestination,用于显示导航内容区(第一个即可理解为为导航栏,第二个组件可理解为内容区); 内容区部分代码:
    build() {
        Column() {
            Navigation() {
                ...                        

                    // 导航组件,默认提供点击响应处理
                    NavRouter() {
                        // 导航区内容
                        ...

                        // NavRouter组件的子组件,用于显示导航内容区。
                        NavDestination() {
                            // 内容区
                            ForEach([0, 1], (item: number) => {
                                Flex({ direction: FlexDirection.Row }) {
                                    Row() {
                                        Image($r('app.media.icon2'))
                                            .width(40)
                                            .height(40)
                                            .borderRadius(40)
                                            .margin({ right: 15 })
                                        Text('今天幸运数字' + index.toString())
                                            .fontSize(20)
                                            .height(40)
                                            .backgroundColor('#f1f9ff')
                                            .borderRadius(10)
                                            .padding(10)
                                    }
                                    .padding({ left: 15 })
                                    .margin({ top: 15 })
                                }
                            }, item => item)
                            ....                                           
                        }

                        // 设置内容区标题
                        .title(this.NavigationTitle(index))
                    }
            }
            //  Navigation组件默认为自适应模式,此时mode属性为NavigationMode.Auto。自适应模式下,当设备宽度大于520vp时,Navigation组件采用分栏模式,反之采用单页面模式。
            .mode(NavigationMode.Auto)
            .hideTitleBar(true)
            .hideToolBar(true)
        }
        .height('100%')
    }

  1. 内容区域的补充:完善内容区域文本组件。 具体代码块如下:
    ...  
    Column() {
            TextArea({
                placeholder: '请输入文字',
            })
            .placeholderFont({ size: 16, weight: 400 })
            .width('100%')
            .height($r("app.float.heightFloat"))
            .fontSize(16)
            .fontColor('#182431')
            .backgroundColor('#FFFFFF')
            .borderRadius(0)
        }
        .margin({ top: $r("app.float.marHeightFloat") })
        .height($r("app.float.ColHeightFloat"))
        .justifyContent(FlexAlign.End)
        ...               

完整代码

示例完整代码如下:

@Entry
@Component
struct NavigationExample {
  @State arr: number[] = [0, 1, 2, 3, 4, 5]
  @State dex: number = 0

  @Builder NavigationTitle(index) {
      Column() {
          Row() {
            Text('互动交流' + index + '群')
            .fontColor('#182431')
            .fontSize(20)
            }
        }
    .width($r("app.float.titHeightFloat"))
    }

    build() {
        Column() {
            Navigation() {
                Text('联系人(' + this.arr.length + ')')
                .fontWeight(500)
                .margin({ top: 10, right: 10, left: 19 })
                .fontSize(17)
                List({ initialIndex: 0 }) {
                    // 通过ForEach循环渲染导航栏内容
                    ForEach(this.arr, (item: number, index: number) => {
                        ListItem() {
                            // 导航组件,默认提供点击响应处理
                            NavRouter() {
                                // 导航区内容
                                Column() {
                                    Row() {
                                        Image($r('app.media.icon1'))
                                            .width(35)
                                            .height(35)
                                            .borderRadius(35)
                                            .margin({ left: 3, right: 10 })
                                        Text('互动交流' + item + '群')
                                            .fontSize(22)
                                            .textAlign(TextAlign.Center)
                                    }
                                    .padding({ left: 10 })
                                    .width('100%')
                                    .height(80)
                                    .backgroundColor(this.dex == index ? '#eee' : '#fff')

                                    Divider().strokeWidth(1).color('#F1F3F5')
                                }.width('100%')

                                // NavRouter组件的子组件,用于显示导航内容区。
                                NavDestination() {
                                    ForEach([0, 1], (item: number) => {
                                        Flex({ direction: FlexDirection.Row }) {
                                            Row() {
                                                Image($r('app.media.icon2'))
                                                    .width(40)
                                                    .height(40)
                                                    .borderRadius(40)
                                                    .margin({ right: 15 })
                                                Text('今天幸运数字' + index.toString())
                                                    .fontSize(20)
                                                    .height(40)
                                                    .backgroundColor('#f1f9ff')
                                                    .borderRadius(10)
                                                    .padding(10)
                                            }
                                            .padding({ left: 15 })
                                            .margin({ top: 15 })
                                        }
                                    }, item => item)

                                    Row() {
                                        Text('幸运数字' + item.toString())
                                            .fontSize(20)
                                            .margin({ right: 10 })
                                            .height(40)
                                            .backgroundColor('#68c059')
                                            .borderRadius(10)
                                            .padding(10)
                                        Image($r('app.media.icon3'))
                                            .width(40)
                                            .height(40)
                                            .borderRadius(40)
                                            .margin({ right: 15 })
                                    }
                                    .padding({ left: 15 })
                                    .margin({ top: 150 })
                                    .width('100%')
                                    .direction(Direction.Rtl)

                                    Column() {
                                        TextArea({placeholder: '请输入文字',})
                                            .placeholderFont({ size: 16, weight: 400 })
                                            .width('100%')
                                            .height($r("app.float.heightFloat"))
                                            .fontSize(16)
                                            .fontColor('#182431')
                                            .backgroundColor('#FFFFFF')
                                            .borderRadius(0)
                                    }
                                    .margin({ top: $r("app.float.marHeightFloat") })
                                    .height($r("app.float.ColHeightFloat"))
                                    .justifyContent(FlexAlign.End)
                                }
                                .backgroundColor('#eee')
                                // 设置内容区标题
                                .title(this.NavigationTitle(index))
                            }
                            .width('100%')
                        }
                    }, item => item)
                }
                .height('100%').margin({ top: 12 })
            }
            // Navigation组件mode属性设置为auto。自适应模式下,当设备宽度大于520vp时,Navigation组件采用分栏模式,反之采用单页面模式。
            .mode(NavigationMode.Auto)
            .hideTitleBar(true)
            .hideToolBar(true)
        }
        .height('100%')
    }
}

为了能让大家更好的学习鸿蒙(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.coloradmin.cn/o/1548419.html

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

相关文章

Alpha律所管理系统,助力律师团队管理提效再升级

律师团队管理,是律所成长与发展经久不衰的议题。无论是律所的创办还是扩张,管理者首先要考虑的就是管理模式的选择与更新问题,这几乎成为一个律所能否长远发展的关键“七寸”。那么,到底为什么团队管理如此重要,做好管…

【实现100个unity特效之7】unity 3d实现各种粒子效果

文章目录 先看最终效果下雨效果萤火虫和火花四溅的效果 3d下雨粒子效果涟漪效果雨滴和涟漪效果结合水花效果雨滴涟漪水花结合问题雾气效果萤火虫火花效果萤火虫和火花效果结合其他特效爆炸、闪电、火焰、雷雨特效(2023/7/5更新)源码完结 先看最终效果 下…

冰岛人[天梯赛]

文章目录 题目描述思路AC代码 题目描述 输入样例 15 chris smithm adam smithm bob adamsson jack chrissson bill chrissson mike jacksson steve billsson tim mikesson april mikesdottir eric stevesson tracy timsdottir james ericsson patrick jacksson robin patrickss…

图片如何做成二维码?手机扫码看图的制作方法

现在用二维码来展示图片、照片时很常用的一种方式,通过扫秒二维码就能够在手机上预览图片,更加的方便快捷。在制作图片二维码的时候,有些情况下需要不定时的在二维码图案不变的情况经常性的修改内容,或者除了图片之外还要加入其它…

【数据结构】受限制的线性表——队列

🧧🧧🧧🧧🧧个人主页🎈🎈🎈🎈🎈 🧧🧧🧧🧧🧧数据结构专栏🎈🎈🎈&…

最新版CleanMyMac X4.15.2有哪些亮眼的更新?

CleanMyMac X是一款专为macOS系统设计的清理和优化工具,它集成了多种功能来帮助用户保持Mac系统的整洁、高效和安全。 首先,CleanMyMac X具备智能扫描和清理功能,能够自动识别并清理Mac上的各种垃圾文件,包括重复文件、无用的语言…

《AI绘画与修图实战:Photoshop+Firefly从入门到精通》

关键点 1.自学教程:内容安排由浅入深、循序渐进,130多个经典AI案例案例助你在实战中掌握技巧 2.技术手册:透彻讲解PSAI、Firefly+AI的绘画和修图实战技巧,高效率学习 3.老师讲解:赠送170分钟频教程和数百个…

企业内推平台招聘信息采集与分析在线项目实习

师傅带练 项目背景 为了实现有效的招聘,企业需要制定明确的招聘需求,根据业务发展需求和市场变化,精准定位所需人才的类型和层次,提高招聘效率和质量。而招聘网站需要积极满足企业的需求,提供针对性的服务&#xff0…

c语言--跳出continue、break

C 语言中的 continue 语句有点像 break 语句。但它不是强制终止,continue 会跳过当前循环中的代码,强迫开始下一次循环。 对于 for 循环,continue 语句执行后自增语句仍然会执行。对于 while 和 do…while 循环,continue 语句重新…

【面试题】数据底层原理:Elasticsearch写入流程解析

前言:本篇博客将介绍Elasticsearch的数据底层原理,涉及数据写入的过程以及相关概念。我们将深入探讨buffer、translog、refresh、commit、flush和merge等核心概念,帮助您更好地理解Elasticsearch的数据存储机制。 写入数据的基本过程 Elast…

【牛客】【刷题节】美团2024届秋招笔试第一场编程真题

1.小美的外卖订单【简单题】 题意理解: 这道题是简单题,主要是一个逻辑实现和判断的问题。但是简单题一般喜欢加一点小障碍,所以读题的时候就要比较注意一些约束条件。就比如这道题:过了15/20个测试用例,出现error, 当…

蓝桥杯小白月赛3.23

题目描述&#xff1a; AC代码&#xff1a; #include <iostream> #include<cstring> #include<algorithm>using namespace std;const int N 2e510; string str[N]; //写上&会速度更快一些 bool cmp(const string &s1,const string &s2) {//例…

金色传说:SAP-PP-CO01/CO02生产订单释放时增强:检查并显示下层组件在不合格库存地库存

文章目录 需求场景一、实现的效果二、实现步骤1.创建自建表2.增强代码 三、重磅福利 需求场景 计划员释放订单时,如果下层组件在不合格库存中有库存时,应先确认不合格库存地库存是否可用,已避免重复生产和库存积压. 因此,提出此需求: 在生产订单下达(释放)时,要提示下层组件在…

七段码(蓝桥杯)

文章目录 七段码题目描述答案&#xff1a;80分析编程求解&#xff1a;有多种方法方法一&#xff1a;状态压缩枚举构图&#xff08;以二极管为顶点&#xff09;DFS判断连通代码方法二&#xff1a;bfs 七段码 题目描述 小蓝要用七段码数码管来表示一种特殊的文字。 上图给出了…

python和Vue开发的RBAC用户角色权限管理系统

后端框架&#xff1a;python的FastAPI作为后端服务和python-jose作为JWT认证 前端框架&#xff1a;Vue3构建页面和Vue Router作为路由管理&#xff0c;Pinia作为数据存储&#xff0c;Vite作为打包工具 可以实现菜单控制和路由控制&#xff0c;页面里面有按钮权限控制&#xf…

css预处理器scss的使用如何全局引入

目录 scss 基本功能 1、嵌套 2、变量 $ 3、mixin 和 include 4、extend 5、import scss 在项目中的使用 1、存放 scss 文件 2、引入 variables 和 mixins 2-1、局部引入 2-2、全局引入 3、入口文件中引入其他文件 项目中使用 css 预处理器&#xff0c;可以提高 cs…

输入与输出

输入(Scanner类) Scanner是java5的新特性&#xff0c;在java.util包里&#xff0c;可以完成用户输入。步骤&#xff1a; 导入java.util包&#xff1b;构造Scanner对象&#xff0c;参数为u标准输入流System.in&#xff1b;使用next()方法系列接收数据 nextBoolean()接收一个布…

P6学习:解析P6 WBS-工作分解结构的原则

前言 WBS&#xff0c;及Work Breakdown Structure&#xff0c;中文工作分解结构&#xff0c;是总结工作阶段的项目的层次结构分解。 WBS 就像项目的大纲——它将项目分解为特定的可交付成果或阶段。 然后将活动添加到这些层中以创建项目计划的时间表。 WBS 使用流程会有所不…

【SpringBoot整合系列】SpringBoot3.x整合Swagger

目录 产生背景官方解释&#xff1a;作用SpringBoot3整合Swagger注意事项swagger3 常用注解SpringBoot3.x整合Swagger1.创建工程(jdk:17,boot:3.2.4)2.引入pom依赖3.application.yml添加配置4.添加swagger3.0配置5.控制器层(Controller)6.模型层(Model)7.启动并测试【Get请求接口…

任务管理工具Trello体验如何?一文揭秘

Trello是一款高效的协作与工作管理应用&#xff0c;这里我们将详细介绍Trello的功能、特点、优劣势、价格、定价、发展历程、使用场景以及使用技巧等等。 一、Trello 是什么 Trello是一款高效的协作与工作管理应用&#xff0c;设计用于跟踪团队项目、凸显当前活动任务、指派责…