纯血鸿蒙APP实战开发——自界说安全键盘案例

嚴華  金牌会员 | 2024-6-14 21:28:28 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 915|帖子 915|积分 2745

介绍

金融类应用在密码输入时,一般会使用自界说安全键盘。本示例介绍怎样使用TextInput组件实现自界说安全键盘场景,主要包罗TextInput.customKeyboard绑定自界说键盘、自界说键盘结构和状态更新等知识点。
结果图预览


实现思路

1. 使用TextInput的customKeyboard的属性方法来设置自界说键盘

当设置自界说键盘时,输入框激活后不会打开系统输入法,而是加载应用指定的自界说组件,针对系统键盘的enterKeyType属性设置将无效。自界说键盘采用覆盖原始界面的方式呈现,不会对应用原始界面产生压缩或者上提。默认在输入控件失去核心时,关闭自界说键盘,开发者也可以通过TextInputController.stopEditing方法控制键盘关闭。
2. 自界说键盘结构

键盘罗列范例:


  • 键盘范例分为数字键盘,大写、小写键盘,特别字符键盘
  • 键盘按键范例分为输入操作INPUT、删除操作DELETE、切换数字键盘操作NUMERIC、切换大小写键盘CAPSLOCK、切换数字键盘SPECIAL共五种范例
  1. /**
  2. * 键盘类型枚举
  3. */
  4. export enum EKeyboardType {
  5.   NUMERIC,    //数字键盘
  6.   UPPERCASE,  // 大写字母键盘
  7.   LOWERCASE,  // 小写字母键盘
  8.   SPECIAL,    // 特殊字符键盘
  9. }
  10. /**
  11. * 键盘按键类型枚举
  12. */
  13. export enum EKeyType {
  14.   INPUT,   // 输入类型,输入具体的值
  15.   DELETE,  // 删除一个输入字符
  16.   NUMERIC, // 切换数字键盘
  17.   CAPSLOCK, // 切换大小写键盘
  18.   SPECIAL, //  切换特殊字符键盘
  19. }
复制代码
在真实业务场景下,自界说安全键盘数据包罗值、UI属性、位置等都通过数据哀求来下发,键盘按键数据接口界说如下:
  1. /**
  2. * 键盘按键数据接口
  3. */
  4. export interface IKeyAttribute {
  5.   label: string | Resource;
  6.   value?: string;
  7.   type?: EKeyType;
  8.   fontSize?: number;
  9.   fontColor?: string | Color;
  10.   backgroundColor?: string | Color;
  11.   position?: [number, number, number, number];
  12. }
复制代码
自界说键盘结构:分为标题栏和键盘两部分,键盘使用Grid结构,每个按键GridItem的值、UI属性和位置都通过数据哀求下发,不必要额外计算。
数字键盘为4*3的网格结构,但是大小写键盘和特别字符键盘的结构为不规则结构,如果设置为4 * 10的网格,有的按键占用1 * 1.5,但是GridItem属性不支持占用非整数列。本文将该场景下将网格拆分为更小的单位,为4 * 20网格结构,每个字母按键占1 * 2,删除按键则占1 * 3,空格则占1 * 10,这样就包管每个按键都要占用整数单位。
  1. Column() {
  2.   this.titleBar();
  3.   Grid() {
  4.     ForEach(this.items, (item: IKeyAttribute) => {
  5.       GridItem() {
  6.         this.myGridItem(item)
  7.       }
  8.       .width('100%')
  9.       .height(this.itemHeight)
  10.       .rowStart(item?.position?.[0])
  11.       .columnEnd(item?.position?.[1])
  12.       .columnStart(item?.position?.[2])
  13.       .columnEnd(item?.position?.[3])
  14.       .backgroundColor(item.backgroundColor)
  15.       .borderRadius($r("app.integer.key_border_radius"))
  16.       .onClick(() => {
  17.             ....
  18.       })
  19.     }, (item: IKeyAttribute, index: number) => JSON.stringify(item) + index)
  20.   }
  21.   .margin({ bottom: $r("app.integer.key_board_marin_bottom") })
  22.   .columnsTemplate(this.curKeyboardType === EKeyboardType.NUMERIC ? "1fr 1fr 1fr" :
  23.     "1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr")
  24.   .rowsTemplate("1fr 1fr 1fr 1fr") // Grid高度均分成4份
  25.   .rowsGap(this.rowSpace) // 设置行间距
  26.   .columnsGap(this.columnSpace) // 设置列间距
  27.   .width('100%')
  28.   .height(this.itemHeight * this.rowCount + this.rowSpace * (this.rowCount - 1))
  29. }
  30. .width('100%')
  31. .padding({ left: this.columnSpace, right: this.columnSpace })
  32. .backgroundColor(Color.Black)
  33. }
复制代码
3. 状态更新

主要是子组件自界说键盘的按键事件怎样通报到父组件,可以在父组件界说好键盘按键事件相应函数onKeyboardEvent,通报给子组件,然后子组件按键时调用父组件通报过来的onKeyboardEvent即可。必要注意的是,在子组件中,必须界说inputValue且使用@Link装饰器,这样能包管子组件调用时onKeyboardEvent时inputValue不为空,父子组件数据双向更新。
  1. @Component
  2. export struct CustomSafeKeyboardView {
  3.   @State inputValue: string = '';
  4.   @State items: IKeyAttribute[] = numericKeyData;
  5.   @State curKeyboardType: EKeyboardType = EKeyboardType.NUMERIC;
  6.   controller: TextInputController = new TextInputController();
  7.   /**
  8.    * 键盘按键事件响应函数
  9.    * @param item
  10.    */
  11.   onKeyboardEvent(item: IKeyAttribute) {
  12.     switch (item.type) {
  13.       // 输入类型,更新输入内容
  14.       case EKeyType.INPUT:
  15.         this.inputValue += item.value;
  16.         break;
  17.       // 删除一个已输入的末尾字符
  18.       case EKeyType.DELETE:
  19.         this.inputValue = this.inputValue.slice(0, -1);
  20.         break;
  21.       // 切换数字字符键盘
  22.       case EKeyType.NUMERIC:
  23.         if (this.curKeyboardType !== EKeyboardType.NUMERIC) {
  24.           this.curKeyboardType = EKeyboardType.NUMERIC;
  25.           this.items = numericKeyData;
  26.         }
  27.         break;
  28.       // 切换大小写
  29.       case EKeyType.CAPSLOCK:
  30.         if (this.curKeyboardType === EKeyboardType.LOWERCASE) {
  31.           // 切换大写字母键盘
  32.           this.curKeyboardType = EKeyboardType.UPPERCASE;
  33.           this.items = upperCaseKeyData;
  34.         } else {
  35.           // 切换小写字母键盘
  36.           this.curKeyboardType = EKeyboardType.LOWERCASE;
  37.           this.items = lowerCaseKeyData;
  38.         }
  39.         break;
  40.       // 切换特殊字符键盘
  41.       case EKeyType.SPECIAL:
  42.         if (this.curKeyboardType !== EKeyboardType.SPECIAL) {
  43.           this.curKeyboardType = EKeyboardType.SPECIAL;
  44.           this.items = specialKeyData;
  45.         }
  46.         break;
  47.       default:
  48.         console.info(`Sorry, we are out of input type.`);
  49.     }
  50.   }
  51.   /**
  52.    * 自定义键盘组件Builder
  53.    */
  54.   @Builder
  55.   customKeyboardBuilder() {
  56.     CustomKeyboard({
  57.       items: this.items,
  58.       inputValue: this.inputValue,
  59.       curKeyboardType: this.curKeyboardType,
  60.       onKeyboardEvent: this.onKeyboardEvent,
  61.       controller: this.controller
  62.     })
  63.   }
  64.   build() {
  65.     Column() {
  66.       Row()
  67.         .height($r("app.integer.row_height"))
  68.       Image($r("app.media.avatar"))
  69.         .width($r("app.integer.avatar_weight"))
  70.         .height($r("app.integer.avatar_height"))
  71.         .objectFit(ImageFit.Fill)
  72.       Text($r("app.string.account_name"))
  73.         .fontSize($r("app.integer.text_font_size"))
  74.         .margin({ top: $r("app.integer.common_margin_padding") })
  75.       TextInput({
  76.         text: this.inputValue,
  77.         placeholder: $r("app.string.placeholder"),
  78.         controller: this.controller
  79.       })// 绑定自定义键盘
  80.         .type(InputType.Password)
  81.         .customKeyboard(this.customKeyboardBuilder())// 绑定自定义安全键盘
  82.         .height($r("app.integer.text_input_height"))
  83.         .border(null)
  84.         .margin({ top: $r("app.integer.common_margin_padding") })
  85.       Button($r("app.string.login_button_label"))
  86.         .type(ButtonType.Capsule)
  87.         .fontSize($r("app.integer.login_button_font_size"))
  88.         .width($r("app.integer.login_button_width"))
  89.         .height($r("app.integer.login_button_height"))
  90.         .margin({ top: $r("app.integer.login_button_margin") })
  91.         .backgroundColor(Color.Pink)
  92.         .onClick(() => {
  93.           this.controller.stopEditing();
  94.         })
  95.     }
  96.     .width($r("app.string.one_hundred_percent"))
  97.     .height($r("app.string.one_hundred_percent"))
  98.     .padding($r("app.integer.common_margin_padding"))
  99.   }
  100. }
复制代码
高性能知识点

不涉及
工程结构&模块范例

  1. customsafekeyboard              // har类型
  2. |---components                  // 自定义组件
  3. |   ---CustomKeyboard.ets  
  4. |---model                       // 模型层
  5. |   ---Constants                // 定义常量数据
  6. |---CustomSafeKeyboardView.ets  // 主页面
复制代码
模块依赖


  • 依赖common模块来实现日志的打印
  • 依赖路由模块,供entry模块实现路由导航
参考资料

TextInput
鸿蒙全栈开发全新学习指南

也为了积极培养鸿蒙生态人才,让大家都能学习到鸿蒙开发最新的技术,针对一些在职人员、0基础小白、应届生/计算机专业、鸿蒙爱好者等人群,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线【包含了大厂APP实战项目开发】
本路线共分为四个阶段:

第一阶段:鸿蒙初中级开发必备技能


第二阶段:鸿蒙南北双向高工技能基础:gitee.com/MNxiaona/733GH


第三阶段:应用开发中高级就业技术


第四阶段:全网首发-工业级南向设备开发就业技术:https://gitee.com/MNxiaona/733GH


《鸿蒙 (Harmony OS)开发学习手册》(共计892页)

怎样快速入门?

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

开发基础知识:gitee.com/MNxiaona/733GH

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

基于ArkTS 开发

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

鸿蒙开发面试真题(含参考答案):gitee.com/MNxiaona/733GH


鸿蒙入门教学视频:


美团APP实战开发教学:gitee.com/MNxiaona/733GH


写在末了



  • 如果你觉得这篇内容对你还蛮有帮助,我想约请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以等待后续文章ing

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

嚴華

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表