HarmonyOS鸿蒙开发实战(5.0)自定义安全键盘场景实践

news/2024/9/28 17:07:56/

鸿蒙HarmonyOS开发实战往期必看文章:(持续更新......)

HarmonyOS NEXT应用开发性能实践总结(持续更新......)

HarmonyOS NEXT应用开发案例实践总结合集(持续更新......)

一分钟了解”纯血版!鸿蒙HarmonyOS Next应用开发!

最新版!“非常详细的” 鸿蒙HarmonyOS Next应用开发学习路线!(从零基础入门到精通)


介绍

金融类应用在密码输入时,一般会使用自定义安全键盘。本示例介绍如何使用TextInput组件实现自定义安全键盘场景,主要包括TextInput.customKeyboard绑定自定义键盘、自定义键盘布局和状态更新等知识点。

效果图预览

实现思路

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

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

2. 自定义键盘布局

键盘枚举类型:

  • 键盘类型分为数字键盘,大写、小写键盘,特殊字符键盘
  • 键盘按键类型分为输入操作INPUT、删除操作DELETE、切换数字键盘操作NUMERIC、切换大小写键盘CAPSLOCK、切换数字键盘SPECIAL共五种类型
/*** 键盘类型枚举*/
export enum EKeyboardType {NUMERIC,    //数字键盘UPPERCASE,  // 大写字母键盘LOWERCASE,  // 小写字母键盘SPECIAL,    // 特殊字符键盘
}/*** 键盘按键类型枚举*/
export enum EKeyType {INPUT,   // 输入类型,输入具体的值DELETE,  // 删除一个输入字符NUMERIC, // 切换数字键盘CAPSLOCK, // 切换大小写键盘SPECIAL, //  切换特殊字符键盘
}

在真实业务场景下,自定义安全键盘数据包括值、UI属性、位置等都通过数据请求来下发,键盘按键数据接口定义如下:


/*** 键盘按键数据接口*/
export interface IKeyAttribute {label: string | Resource;value?: string;type?: EKeyType;fontSize?: number;fontColor?: string | Color;backgroundColor?: string | Color;position?: [number, number, number, number];
}

自定义键盘布局:分为标题栏和键盘两部分,键盘使用Grid布局,每个按键GridItem的值、UI属性和位置都通过数据请求下发,不需要额外计算。

数字键盘为4*3的网格布局,但是大小写键盘和特殊字符键盘的布局为不规则布局,如果设置为4 * 10的网格,有的按键占用1 * 1.5,但是GridItem属性不支持占用非整数列。本文将该场景下将网格拆分为更小的单元,为4 * 20网格布局,每个字母按键占1 * 2,删除按键则占1 * 3,空格则占1 * 10,这样就保证每个按键都要占用整数单元。

Column() {this.titleBar();Grid() {ForEach(this.items, (item: IKeyAttribute) => {GridItem() {this.myGridItem(item)}.width('100%').height(this.itemHeight).rowStart(item?.position?.[0]).columnEnd(item?.position?.[1]).columnStart(item?.position?.[2]).columnEnd(item?.position?.[3]).backgroundColor(item.backgroundColor).borderRadius($r("app.integer.key_border_radius")).onClick(() => {....})}, (item: IKeyAttribute, index: number) => JSON.stringify(item) + index)}.margin({ bottom: $r("app.integer.key_board_marin_bottom") }).columnsTemplate(this.curKeyboardType === EKeyboardType.NUMERIC ? "1fr 1fr 1fr" :"1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr").rowsTemplate("1fr 1fr 1fr 1fr") // Grid高度均分成4份.rowsGap(this.rowSpace) // 设置行间距.columnsGap(this.columnSpace) // 设置列间距.width('100%').height(this.itemHeight * this.rowCount + this.rowSpace * (this.rowCount - 1))
}
.width('100%')
.padding({ left: this.columnSpace, right: this.columnSpace })
.backgroundColor(Color.Black)
}
3. 状态更新

主要是子组件自定义键盘的按键事件如何传递到父组件,可以在父组件定义好键盘按键事件响应函数onKeyboardEvent,传递给子组件,然后子组件按键时调用父组件传递过来的onKeyboardEvent即可。需要注意的是,在子组件中,必须定义inputValue且使用@Link装饰器,这样能保证子组件调用时onKeyboardEvent时inputValue不为空,父子组件数据双向更新。

@Component
export struct CustomSafeKeyboardView {@State inputValue: string = '';@State items: IKeyAttribute[] = numericKeyData;@State curKeyboardType: EKeyboardType = EKeyboardType.NUMERIC;controller: TextInputController = new TextInputController();/*** 键盘按键事件响应函数* @param item*/onKeyboardEvent(item: IKeyAttribute) {switch (item.type) {// 输入类型,更新输入内容case EKeyType.INPUT:this.inputValue += item.value;break;// 删除一个已输入的末尾字符case EKeyType.DELETE:this.inputValue = this.inputValue.slice(0, -1);break;// 切换数字字符键盘case EKeyType.NUMERIC:if (this.curKeyboardType !== EKeyboardType.NUMERIC) {this.curKeyboardType = EKeyboardType.NUMERIC;this.items = numericKeyData;}break;// 切换大小写case EKeyType.CAPSLOCK:if (this.curKeyboardType === EKeyboardType.LOWERCASE) {// 切换大写字母键盘this.curKeyboardType = EKeyboardType.UPPERCASE;this.items = upperCaseKeyData;} else {// 切换小写字母键盘this.curKeyboardType = EKeyboardType.LOWERCASE;this.items = lowerCaseKeyData;}break;// 切换特殊字符键盘case EKeyType.SPECIAL:if (this.curKeyboardType !== EKeyboardType.SPECIAL) {this.curKeyboardType = EKeyboardType.SPECIAL;this.items = specialKeyData;}break;default:console.info(`Sorry, we are out of input type.`);}}/*** 自定义键盘组件Builder*/@BuildercustomKeyboardBuilder() {CustomKeyboard({items: this.items,inputValue: this.inputValue,curKeyboardType: this.curKeyboardType,onKeyboardEvent: this.onKeyboardEvent,controller: this.controller})}build() {Column() {Row().height($r("app.integer.row_height"))Image($r("app.media.avatar")).width($r("app.integer.avatar_weight")).height($r("app.integer.avatar_height")).objectFit(ImageFit.Fill)Text($r("app.string.account_name")).fontSize($r("app.integer.text_font_size")).margin({ top: $r("app.integer.common_margin_padding") })TextInput({text: this.inputValue,placeholder: $r("app.string.placeholder"),controller: this.controller})// 绑定自定义键盘.type(InputType.Password).customKeyboard(this.customKeyboardBuilder())// 绑定自定义安全键盘.height($r("app.integer.text_input_height")).border(null).margin({ top: $r("app.integer.common_margin_padding") })Button($r("app.string.login_button_label")).type(ButtonType.Capsule).fontSize($r("app.integer.login_button_font_size")).width($r("app.integer.login_button_width")).height($r("app.integer.login_button_height")).margin({ top: $r("app.integer.login_button_margin") }).backgroundColor(Color.Pink).onClick(() => {this.controller.stopEditing();})}.width($r("app.string.one_hundred_percent")).height($r("app.string.one_hundred_percent")).padding($r("app.integer.common_margin_padding"))}
}

高性能知识点

不涉及

工程结构&模块类型

customsafekeyboard              // har类型
|---components                  // 自定义组件
|   ---CustomKeyboard.ets  
|---model                       // 模型层
|   ---Constants                // 定义常量数据
|---CustomSafeKeyboardView.ets  // 主页面

模块依赖

  1. 依赖common模块来实现日志的打印
  2. 依赖路由模块,供entry模块实现路由导航

最后

小编在之前的鸿蒙系统扫盲中,有很多朋友给我留言,有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)路线图、学习视频、文档用来跟着学习是非常有必要的。 

如果你是一名有经验的资深Android移动开发、Java开发、前端开发、对鸿蒙感兴趣以及转行人员

鸿蒙 NEXT 全栈开发学习笔记  希望这一份鸿蒙学习文档能够给大家带来帮助~

这份鸿蒙(HarmonyOS NEXT)包含了鸿蒙开发必掌握的核心知识要点,内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、(南向驱动、嵌入式等)鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。


鸿蒙(HarmonyOS NEXT)最新学习路线

该路线图包含基础技能、就业必备技能、多媒体技术、六大电商APP、进阶高级技能、实战就业级设备开发,不仅补充了华为官网未涉及的解决方案

路线图适合人群:

IT开发人员:想要拓展职业边界
零基础小白:鸿蒙爱好者,希望从0到1学习,增加一项技能。
技术提升/进阶跳槽:发展瓶颈期,提升职场竞争力,快速掌握鸿蒙技术

2.视频学习教程+学习PDF文档

HarmonyOS Next 最新全套视频教程 全球开发者的开源社区,开源代码

  纯血版鸿蒙全套学习文档(面试、文档、全套视频等)  全球开发者的开源社区,开源代码

​​

鸿蒙大厂面试真题》GitCode - 全球开发者的开源社区,开源代码

总结

参与鸿蒙开发,你要先认清适合你的方向,如果是想从事鸿蒙应用开发方向的话,可以参考本文的学习路径,简单来说就是:为了确保高效学习,建议规划清晰的学习路线


http://www.ppmy.cn/news/1530670.html

相关文章

Linux系统备份Gitee等云git所有仓库与所有分支的数字资产

思路: 1. ssh 配置 2. reps.txt 列出所有仓库名 3. exp的自动化备份脚本 -- 环境安装: exp需要依赖安装的文件,所以先执行下(以ubuntu为例): sudo apt-get install expect 操作步骤: ssh 配置 1. 添加公钥至 …

CoreDNS实现跨集群service解析实践

CoreDNS实现跨集群service解析实践 背景介绍使用条件实现方案 CoreDNS是一款使用Go语言实现的专为云原生应用而生的DNS服务器。本文介绍CoreDNS在特定实际场景下的一种进阶使用实践,也许能为其他也在使用CoreDNS做服务发现的同学提供一些启发和思考。 背景介绍 在…

使用AI进行需求分析的案例研究

生成式 AI 的潜在应用场景似乎无穷无尽。虽然这令人兴奋,但也可能让人不知所措。因此,团队在使用这项技术时需要有明确的目标:关键是要明确生成式 AI 在团队工作中能产生哪些实质性影响。 在软件工程中,一个引人注目的应用场景是…

Python Web 面试题

1 Web 相关 get 和 post 区别 get: 请求数据在 URL 末尾,URL 长度有限制 请求幂等,即无论请求多少次,服务器响应始终相同,这是因为 get 至少获取资源,而不修改资源 可以被浏览器缓存,以便以后…

LeetCode 1014. 最佳观光组合 一次遍历数组,时间复杂度O(n)

1014. 最佳观光组合 today 1014 最佳观光组合 题目描述 给定正整数数组 A&#xff0c;A[i] 表示第 i 个观光景点的评分&#xff0c;评分由 1 到 10^6 之间的整数。 一对景点&#xff08;A[i], A[j]&#xff09;的观光总得分为 A[i] A[j] i - j&#xff0c;其中 i < j。…

付费进群V5版本首发源码

付费进群V5版本首发 最新分站大屏 更新三个模板 仿官方模板等等 最新防注入技术 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/89797314 更多资源下载&#xff1a;关注我。

【递归】5.leetcode 872 叶子相似的树

1 题目描述 题目链接&#xff1a;叶子相似的树 2 解答思路 递归分为三步&#xff0c;接下来就按照这三步来思考问题 第一步&#xff1a;挖掘出相同的子问题 &#xff08;关系到具体函数头的设计&#xff09; 第二步&#xff1a;只关心具体子问题做了什么 &#xff08;关…

工业交换机如何保证数据的访问安全

在现代工业自动化环境中&#xff0c;工业交换机作为关键的网络设备&#xff0c;扮演着数据传输和信息交互的重要角色。为了确保数据的访问安全&#xff0c;工业交换机不仅具备高效的转发性能&#xff0c;还集成了多层次的安全防护机制&#xff0c;以抵御各种潜在的网络威胁。 首…