往期推文全新看点

概述

本文从目前流行的垂类市场中,选择地图行业应用作为典型案例详细介绍 “一多” 在实际开发中的应用。地图行业核心功能为定位、导航和打车等。根据这些核心功能,本文选择 首页 、 路线规划页 、 服务卡片页 、 实况窗页 等作为典型页面进行开发,遵从多设备的“差异性”、“一致性”、“灵活性”和“兼容性”,能够让开发者快速高效地掌握“一多”能力并实现地图导航应用的相关功能。

地图类应用为了提升用户的使用体验,对垂类内的核心功能进行了独特设计:

  • 首页 为了减少面板对地图的遮挡,采用手机端使用底部面板,而折叠屏展开态使用侧边面板的方式展示功能入口。
  • 面板高度支持多档位调节,以根据用户需求展示信息。手机端及折叠屏默认中档位高度,用户在查看地图的同时可以看到常用的功能。宽屏设备屏幕空间充裕,面板可以拖拽至右侧。
  • 用户查看 地点详情 时,选择地点后,地点详情信息展示在面板上。
  • 在 搜索结果页 中,搜索框始终展示在面板上,避免遮挡地图视野。
  • 在 路线规划页 中,用户上滑或下滑面板时,路线推荐方案布局自适应变化,以在不同大小的面板上展示相同的路线信息。
  • 在宽屏设备上, 导航页 通过侧边小弹窗及侧边底部面板展示路线信息,避免遮挡地图视野。
  • 应用提供 服务卡片页 ,展示常用功能、常用地点或路况信息等用户关注的内容,用户可以通过卡片进入应用。
  • 实况窗页 可以在屏幕左上角实时更新定位、导航或打车的关键信息,并在通知中心中实时更新更多关键信息。

架构设计

HarmonyOS的分层架构主要包括三个层次:产品定制层、基础特性层和公共能力层,为开发者构建了一个清晰、高效、可扩展的设计架构。

页面开发

本章介绍地图导航应用中如何使用“一多”的布局能力,完成页面层级的一套页面、多端适配。下文将从不同页面展开,介绍每个页面区域使用到的具体的布局能力,帮助开发者从0到1进行地图导航应用的开发。

首页

首页通常在地图上展示当前位置信息,并且提供搜索地点、查看地点详情等功能入口,便于用户操作。观察首页在不同设备上的UX设计图,可以进行如下设计:

  • 将首页分为6个区域,效果图如下:
sm md
效果图
  • 对其中的各个区域分析使用的能力,实现方案如下表:
区域编号 简介 实现方案
1 地图 使用 MapComponent 组件实现地图的展示,默认占满窗口,并设置窗口的沉浸式。
2 面板 使用 Stack 组件,在地图上层嵌套 Column 组件实现面板,并借助 栅格布局 监听断点变化,设置在不同断点下面板的不同形态。在sm断点下面板底部展示,在md断点下悬浮展示。并通过绑定 拖动手势 实现在宽屏设备上的居左或居右变换。
3 拖动区域 通过绑定 拖动手势 实现面板高度变换,当前支持三个档位变换调节。
4 搜索框 使用 TextInput 组件实现搜索框效果,通过 onSubmit 事件实现搜索功能。
5 功能选择 使用 Grid 组件实现均分能力,并在面板高度切换时,展示不同行数的功能。
6 页签 Tabs组件实现延伸能力。
  • 面板通过Stack组件,在MapComponent上嵌套Column实现,并通过手势的判定,实现面板多档位调节及位置改变。
// features/map/src/main/ets/view/MapView.ets
build() {
  Stack({ alignContent: Alignment.BottomStart }) {
    MapComponent({ mapOptions: this.mapOption, mapCallback: this.callback })

    Column() {
      Row() {
        // ...
      }
      .height($r('app.float.bar_height'))
      .width(Common.FULL_WIDTH)
      .justifyContent(FlexAlign.Center)
      .gesture(
        PanGesture(this.panOptionHeight)
          .onActionStart((event?: GestureEvent) => {
            Logger.info('Height change pan start.');
          })
          .onActionUpdate((event?: GestureEvent) => {
            if (event) {
              let height = this.columnHeight - event.offsetY;
              this.tempColumnHeight = height;
              if (this.tempColumnHeight < Common.HEIGHT_LOW) {
                this.tempColumnHeight = Common.HEIGHT_LOW;
              }
              if (this.tempColumnHeight > this.columnMaxHeight) {
                this.tempColumnHeight = this.columnMaxHeight;
              }
            }
          })
          .onActionEnd(() => {
            if (this.tempColumnHeight > (this.columnMaxHeight - Common.HEIGHT_MIDDLE) / 2 + Common.HEIGHT_MIDDLE) {
              this.columnHeight = this.columnMaxHeight;
              this.isShowBack = false;
            } else if (this.tempColumnHeight < (Common.HEIGHT_MIDDLE - Common.HEIGHT_LOW) / 2 + Common.HEIGHT_LOW) {
              this.columnHeight = Common.HEIGHT_LOW;
              this.isShowBack = true;
            } else {
              this.columnHeight = Common.HEIGHT_MIDDLE;
              this.isShowBack = true;
            }
            this.tempColumnHeight = this.columnHeight;
          })
      )
      // ...
    }
    // ...
    .gesture(
      PanGesture(this.panOptionPosition)
        .onActionStart((event?: GestureEvent) => {
          Logger.info('Position change pan start.');
        })
        .onActionUpdate((event?: GestureEvent) => {
          if (event) {
            let position = this.left + event.offsetX;
            this.tempLeft = position;
            if (this.tempLeft < Common.LEFT_MD) {
              this.tempLeft = Common.LEFT_MD;
            }
            if (this.tempLeft > Common.RIGHT_MD) {
              this.tempLeft = Common.RIGHT_MD;
            }
          }
        })
        .onActionEnd(() => {
          if (this.tempLeft < Common.CHANGE) {
            this.left = Common.LEFT_MD;
          } else {
            this.left = Common.RIGHT_MD;
          }
          this.tempLeft = this.left;
        })
    )
    // ...
  }
  .height(Common.FULL_HEIGHT)
  .width(Common.FULL_WIDTH)
}

地点详情页

地点详情页展示用户所选地点的详细信息,并提供导航及路线规划入口。观察地点详情页在不同设备上的UX设计图,可以进行如下设计:

  • 将地点详情页划分为2个区域,效果图如下:
sm md
效果图
  • 对其中的各个区域分析使用的能力,实现方案如下表:
区域编号 简介 实现方案
1 图片轮播区 Swiper 实现图片轮播切换。
2 景点信息 List组件 实现 延伸能力。

搜索结果页

搜索结果页展示根据用户的输入内容得到的附近相关地点列表。观察搜索结果页在不同设备上的UX设计图,可以进行如下设计:

  • 将搜索结果页划分为2个区域,效果图如下:
sm md
搜索结果列表-中档位面板效果
搜索结果列表-高档位面板效果
  • 对其中的各个区域分析使用的能力,实现方案如下表:
区域编号 简介 实现方案
1 搜索框 搜索内容后右侧按钮转变为取消。
2 搜索结果列表 面板处于中档位时采用 Swiper 实现延伸能力,高档位时采用 List组件 实现延伸能力。

路线规划页

路线规划页默认通过驾车路线规划最多三条路线,并展示相关信息。观察路线规划页在不同设备上的UX设计图,可以进行如下设计:

  • 将路线规划页划分为4个区域,效果图如下:
sm md
路线搜索效果
路径规划结果
  • 对其中的各个区域分析使用的能力,实现方案如下表:
区域编号 简介 实现方案
1 输入区域 通过判断当前面板高度更换按钮及输入区域布局, Row 组件配合layoutWeight实现拉伸能力
2 方案页签 Tabs 组件实现延伸能力。
3 常去地点信息 Column 组件实现 延伸能力。
4 路线规划结果 List 组件实现 延伸能力,并在不同面板高度时设置List的不同方向。

导航页

导航页提供实时导航能力,并展示路况信息及剩余路线信息。观察导航页在不同设备上的UX设计图,可以进行如下设计:

  • 将导航页划分为2个区域,效果图如下:
sm md
效果图
  • 对其中的各个区域分析使用的能力,实现方案如下表:
区域编号 简介 实现方案
1 当前路径信息 栅格布局 监听断点变化实现 挪移布局。
2 剩余路线信息 Row 组件设置justifyContent属性为SpaceBetween实现自适应占满。

打车页

打车页展示当前可选择车辆类型及价格等信息,并提供打车能力。观察打车页在不同设备上的UX设计图,可以进行如下设计:

  • 将打车页划分为2个区域,效果图如下:
sm md
效果图
  • 对其中的各个区域分析使用的能力,实现方案如下表:
区域编号 简介 实现方案
1 车辆信息 List 组件实现 延伸能力 。
2 打车 Row 组件实现拉伸效果。

服务卡片页

服务卡片页采用静态卡片展示应用常用功能、地点及路况等信息。观察服务卡片页在不同设备上的UX设计图,可以进行如下设计:

  • 服务卡片效果图如下:
sm md
效果图
  • 对其中的各个区域分析使用的能力,实现方案如下表:
区域编号 简介 实现方案
1 静态卡片 在多端均采用2*4的八宫格静态卡片。
  • 静态卡片的实现

在入口模块创建静态卡片后,添加卡片显示内容,通过FormLink进行静态卡片内部和提供方应用间的交互。

// products/phone/src/main/ets/form/pages/FormCard.ets
Column() {
  FormLink({
    action: this.ACTION_TYPE,
    abilityName: this.ABILITY_NAME,
    params: {
      message: this.MESSAGE
    }
  }) {
    Column() {
      Image($r('app.media.search'))
        .width(FormConstants.FULL_WIDTH)
        .margin({ top: $r('app.float.search_image_margin') })

      Row() {
        ForEach(FormViewData.FUNCTIONS, (item: FunctionType) => {
          Column() {
            Image(item.icon)
              .width($r('app.float.list_image_size'))
              .height($r('app.float.list_image_size'))

            Text(item.desc)
              .fontSize($r('app.float.list_desc_font_size'))
              .padding({ top: $r('app.float.list_desc_margin') })
          }
        }, (item: FunctionType) => item.id.toString())
      }
      .justifyContent(FlexAlign.SpaceBetween)
      .height(FormConstants.LIST_HEIGHT)
      .width(FormConstants.FULL_WIDTH)
      .margin({ bottom: $r('app.float.list_margin') })
    }
    .width(FormConstants.LIST_WIDTH)
    .alignItems(HorizontalAlign.Center)
  }
}
.width(FormConstants.FULL_WIDTH)

实况窗页

实况窗页实现卡片及胶囊两种形态,分别展示在锁屏、通知中心及状态栏。观察实况窗页在不同设备上的UX设计图,可以进行如下设计:

  • 实况窗及实况胶囊效果图如下:
通知中心 状态栏 实况胶囊
效果图
  • 对其中的各个区域分析使用的能力,实现方案如下表:
区域编号 简介 实现方案
1 卡片形态 实况窗默认支持多端效果,本应用实现效果为 强调文本模板 ,实况窗拉起时展示在通知中心、和锁屏界面,点击实况胶囊后展示在状态栏。
2 胶囊形态 实况胶囊默认支持多端效果,本应用实现效果为 文本胶囊 。
  • 应用处于后台运行时,拉起实况窗和实况胶囊。配置相应实况窗及胶囊参数。
// features/live/src/main/ets/viewmodel/LiveViewController.ets
private static async buildDefaultView(): Promise<liveViewManager.LiveView> {
  let idNumber: number = systemDateTime.getTime();
  return {
    id: idNumber,
    event: 'PICK_UP',
    liveViewData: {
      primary: {
        title: LiveConstants.LIVE_VIEW_TITLE,
        content: [
          {
            text: LiveConstants.LIVE_VIEW_CONTENT,
          },
          {
            text: LiveConstants.LIVE_VIEW_DISTANCE,
            textColor: LiveConstants.LICE_VIEW_DISTANCE_COLOR
          }
        ],
        keepTime: LiveConstants.TIME,
        clickAction: await LiveViewController.buildWantAgent(),
        layoutData: {
          layoutType: liveViewManager.LayoutType.LAYOUT_TYPE_PICKUP,
          underlineColor: LiveConstants.UNDERLINE_COLOR,
          title: LiveConstants.TAXI_BRAND_INFO,
          content: LiveConstants.TAXI_LICENCE_INFO,
          descPic: LiveConstants.TAXI_ICON
        }
      },
      capsule: {
        type: liveViewManager.CapsuleType.CAPSULE_TYPE_TEXT,
        status: 1,
        icon: LiveConstants.CAPSULE_ICON,
        backgroundColor: LiveConstants.CAPSULE_COLOR,
        title: LiveConstants.LIVE_VIEW_DISTANCE
      }
    }
  };
}

最后

总是有很多小伙伴反馈说:鸿蒙开发不知道学习哪些技术?不知道需要重点掌握哪些鸿蒙开发知识点? 为了解决大家这些学习烦恼。在这准备了一份很实用的鸿蒙全栈开发学习路线与学习文档给大家用来跟着学习。

针对一些列因素,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植……等)技术知识点。

《鸿蒙 (Harmony OS)开发学习手册》(共计892页):https://docs.qq.com/doc/DSEd0U29uT3hHbFZK

如何快速入门?

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

在这里插入图片描述

鸿蒙开发面试真题(含参考答案):

在这里插入图片描述

《OpenHarmony源码解析》:

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ……
  • 系统架构分析
  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ……

图片

OpenHarmony 设备开发学习手册:https://docs.qq.com/doc/DSHRVT0NZb05PUklN

图片

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐