#过年不停更#HarmonyOS-ETS之紧急拨号

Posted HarmonyOS技术社区

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#过年不停更#HarmonyOS-ETS之紧急拨号相关的知识,希望对你有一定的参考价值。

春节不停更,此文正在参加「星光计划-春节更帖活动」
作者:陈龙佳

前言

一直在学习关于鸿蒙官方文档,主要是学习基于JS扩展的类web开发范式,而随着开发文档的不断更新,SDK也更新到了8,随着TS的不断广泛应用,于是我就接触了基于TS扩展的类web开发范式,也就是ArkUI。本文主要是基于ArkUI实现的一个小项目,也可以说是一个demo,主要是通过ETS的语法完成一些关于界面相关的、简单的数据通信以及交互。

效果展示

创建项目

首先打开devEco Studio编辑器,左上角找到File-->New-->New project,然后来到下面这个页面,对于第一次使用该编辑器时最令人的头疼的应该就是sdk的问题,首先ETS项目必须需要SDK7以上才可以使用,所以如果有创建失败的童鞋们请检查你们的SDK版本是否正确。

项目架构

目录 描述
src 项目的源码主文件夹
components 公共组件的存放文件夹
Model 主要数据源的存放文件夹
pages 项目页面文件夹
app.ets 项目的入口文件
resources 应用的资源文件夹(字符串、图片、音频等)
config.json 应用配置文件

数据模型构建

1.定义一个接口来约束urgentDialList

// 这里使用TS中的interface来约束接口
interface UrgentDialList 
  id: number,
  EmergencyNumber: number,
  type: string


const urgentDialList: UrgentDialList[] = [
  
    id: 1,
    EmergencyNumber: 110,
    type: "匪警"
  ,
  
    id: 2,
    EmergencyNumber: 120,
    type: "医疗救急"
  ,
  
    id: 3,
    EmergencyNumber: 119,
    type: "火警"
  
]

2.构建initializeOnStartup方法来对页面数据进行初始化处理

export function initializeOnStartup(): Array<UrgentListData> 
  let urgentDialListArray: Array<UrgentListData> = []
  urgentDialList.forEach(item => 
    urgentDialListArray.push(new UrgentListData(item.id, item.EmergencyNumber, item.type))
  )
  return urgentDialListArray

主要涉及到的状态变量装饰器

装饰器 描述
@State 组件拥有的状态属性。每当@State装饰的变量更改时,组件会重新渲染更新UI
@Link 组件依赖于其父组件拥有的某些状态属性。每当任何一个组件中的数据更新时,另一个组件的状态都会更新,父子组件都会进行重新渲染。
@Prop 工作原理类似@Link,只是子组件所做的更改不会同步到父组件上,属于单向传递。

在这里我想说的是关于@Link跟@Prop都可以进行组件数据的传递,但是通过@Prop修饰的变量,父组件不能进行数据的修改,因为这样会破坏数据的单向性,而@Link是双向数据绑定的,可以进行数据的重新渲染以及修改。

主要涉及功能点

  • 打开弹框获取地理位置
  • 紧急拨号页面的跳转
  • 拨号键盘的呼入与呼出
  • 手势事件滑动呼叫紧急号码

主要工具函数类

1.showToast函数

作用:主要用来展示弹框,这里需要引入鸿蒙里一个包(import prompt from @system.prompt;)

async function showToast(message: string,duration:number = 5000) 
  await prompt.showToast(
    message,
    duration
  )

2.routerPage函数

作用:主要用来进行页面跳转,这里需要引入鸿蒙里一个包(import routerfrom @system.router;)

async function routerPage(path) 
  let option = 
    uri: `pages/$path`
  
  try 
    await router.push(option)
   catch (err) 
    console.log(`fail callback, code: $err.code, msg: $err.msg`)
  

组件封装

keyword组件

键盘组件主要使用Grid宫格布局,对于这种类似键盘或者九宫格的布局推荐使用grid布局,
采用网格容器,二维布局,将容器划分成"行"和"列",产生单元格,然后指定"项目所在"的单元格,可以任意组合不同的网格,做出各种各样的布局。
但是要注意一点,Text组件只能用来展示字符串,因此如果是想展示数字的话得需要通过toString()转换一下,这是我之前遇到的一个小问题。

@Component
export default struct Keyword 
  @State keySign: (string | number)[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, "*", 0, "#"]
  @State key: number | string= ""
  @Link inputNumber: string

  build() 
    Column( space: 5 ) 
      Grid() 
        ForEach(this.keySign, key => 
          GridItem() 
            Text(key.toString())
              .fontSize(52)
              .fontColor("#fff")
              .fontWeight(500)
              .width(100%)
              .height(100%)
              .textAlign(TextAlign.Center)
              .onClick(() => 
                console.log(key);
                this.key = this.inputNumber
              )
          
        )
      
       // 这里使用到了grid中的columnsTemplate以及rowsTemplate属性,他会对元素进行区域分割
      .columnsTemplate(1fr 1fr 1fr)
      .rowsTemplate(1fr 1fr 1fr 1fr)
      .columnsGap(10)
      .rowsGap(10)
      .width(90%)
      .height(360)
    
  

urgentList组件

该组件主要用来渲染紧急拨号列表,在ArkUI中,主要使用forEach来遍历数据,进行页面展示。

import urgentListItem from "./urgentListItem.ets"
import UrgentListData from "../Model/urgentListData.ets"
import initializeOnStartup from "../Model/urgentListModel.ets"

@Component
export default struct UrgentList 
  private urgentItems: UrgentListData[]= initializeOnStartup()

  build() 
    List() 
      ForEach(this.urgentItems, item => 
        ListItem() 
          urgentListItem( urgentItems: item )
        
      , item => item.id.toString())
    
    .width("90%")
  

urgentListItem组件

该组件中使用了手势事件,通过PanGesture()中的onActionEnd、onActionStart、onActionUpdate三个方法来对手势所触发的距离进行控制,当this.offsetX大于某一临界值时,滑动改变菜单布局或内容布局的left偏移量,手势抬起完成偏移量进行视图的更新。

1.首先,会使用到手势事件,通过判断手势滑动的偏移量offsetX来控制滑动后颜色改变

gesture():gesture: GestureType,mask?: GestureMask

鸿蒙系统提供如下Gesture类型:

LongPressGesture 长按手势
PanGesture 平移手势
PinchGesture 捏合手势
RotationGesture 旋转手势

2.响应手势事件

  • 组件通过gesture方法绑定手势对象,可以通过手势对象提供的事件相应响应手势操作。如通过TapGesture对象的onAction事件响应点击事件。
//手势事件
      .gesture(
      PanGesture()
        .onActionStart((event: GestureEvent) => 
          console.info(Pan start)
        )
        .onActionUpdate((event: GestureEvent) => 
          //          console.log(typeof `$this.offsetX`);
        )
        .onActionEnd((event: GestureEvent) => 
          console.info(Pan end)
          this.offsetX = event.offsetX
          console.log(`$this.offsetX`);
          if (Number(this.offsetX) > 60) 
            this.bgc = "#d94838"
            this.isSlide = true
             // 使用定时器来关闭滑动后的状态
            this.closeISettimeOut();
          
        )
      )
  • 当响应事件结束后,关闭定时器来关闭滑动,重置效果。

    //关闭定时器 
    closeISettimeOut() 
      if (this.timer) 
        clearTimeout(this.timer)
      
      this.timer = setTimeout(() => 
        this.isSlide = false;
        this.bgc = "rgba(255,255,255,0.30)"
      , 2000)
    

positionInfoDialog组件

功能点:询问是否自动获取地理位置,若继续,则显示当前地理位置,若取消则关闭弹框,显示初始值

@Component
export default struct PositionInfoDialog 
 //  这里的@Link主要用来组件之间传递数据
  @Link isShowDialog: boolean
  @Link userPosition: string

  build() 
    Flex( direction: FlexDirection.Column, alignItems: ItemAlign.Center ) 
      Column() 
        Text("自动获取位置信息服务")
          .height(100)
          .fontSize(28)
          .fontWeight(500)
          .width("100%")
      

      Column() 
        Text("为帮助您更好地发起求助,进入紧急呼叫时,系统将自动获取您的位置信息,并显示在洁面顶部。点击位置信息可跳转至第三方地图应用。")
          .fontSize(16)
          .lineHeight(28)
          .letterSpacing(2)
          .margin( bottom: 10 )
          .fontColor("rgba(0,0,0,0.90)")
        Text("本服务需联网并调用您的位置权限。在紧急呼叫状态中,相关权限将维持打开状态。是否继续?")
          .fontSize(16)
          .lineHeight(28)
          .letterSpacing(2)
          .fontColor("rgba(0,0,0,0.90)")
      .height(220)

      Row() 
        Button(取消,  type: ButtonType.Normal, stateEffect: true )
          .width(150)
          .backgroundColor("#fff")
          .fontColor("#0a59f7")
          .fontSize(30)
          .onClick(() => 
            this.isShowDialog = false
          )

        Button(继续,  type: ButtonType.Normal, stateEffect: true )
          .width(150)
          .backgroundColor("#fff")
          .fontColor("#0a59f7")
          .fontSize(30)
          .onClick(() => 
            if (this.userPosition) 
              this.userPosition="广东省深圳市"
              this.isShowDialog = false
            
          )
      
    
    .padding( left: 14, right: 14, bottom: 20 )
    .margin( bottom: 40 )
    .width("96%")
    .height(360)
    .backgroundColor("#fff")
    .borderRadius(24)
  

总结

本文只是大致的使用ArkUI对页面进行了简单的布局以及事件的交互,没有涉及到太复杂的逻辑功能业务。
鸿蒙的路还很长,青春正好,故事还没有结束,而我们正走在探索的路上。如果想更多的了解以及深入学习鸿蒙生态的知识,可以参阅:ArkUI

项目源码

https://gitee.com/chen_longjia/ark-ui-emergency

更多原创内容请关注:中软国际 HarmonyOS 技术团队

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

想了解更多关于鸿蒙的内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com/#bkwz

::: hljs-center

:::

以上是关于#过年不停更#HarmonyOS-ETS之紧急拨号的主要内容,如果未能解决你的问题,请参考以下文章

#过年不停更#Axios踩坑日记

#过年不停更#HarmonyOS自定义JS组件—灵动的锦鲤

使用紧急拨号器启动 android 应用程序

dialer拨号盘拨打999,显示的不是紧急号码

#打卡不停更#家庭健康管理平台

成长经历之新年感触