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

介绍

金融类应用在密码输入时,一般会使用自定义安全键盘。本示例介绍如何使用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模块实现路由导航

参考资料

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🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请移步前往小编:gitee.com/MNxiaona/733GH

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3015097.html

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

相关文章

借势母亲节h5小游戏的作用是什么

企业商家往往喜欢借势节日开展营销,母亲节作为5月的重要节日自然不可错过,不同行业商家都有自己开展互动想要实现的效果,如品牌宣传曝光、引流及渠道跳转等。 基于微信社交属性,有利于品牌发展,在【雨科】平台拥有多款…

stm32和树莓派的区别?

在开始前我有一些资料,是我根据网友给的问题精心整理了一份「stm32的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!!Stm32和树莓派是两个不同的领域…

MyCat安装

MyCat安装 官网下载地址打不开说明采用站点的方式进行下载基础包 :程序包: 配置原型库数据源root.user.json 配置文件说明(默认配置) Mycat启动授权启动mycat启动mycat查看mycat日志连接Mycat 官网下载地址打不开说明 官网可能受…

二维码怎么播放视频?视频快速转二维码的方法

现在分享视频时,很多人都会采用视频生成二维码的方式,来让其他人通过扫描二维码查看视频。选择使用这种方式可以让更多人同时扫码查看视频,不需要传输或者下载存储,提升视频传播的速度,而且用户的体验效果更好。 那么…

ICC2:如何解决pin density过高引起的绕线问题

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 为了追求极致的利用率,综合往往会使用大量的AOI/OAI等多pin cell,然而后端实现过程中,工具为了解决绕线难题,又会通过降低local density的方法实现反向奔赴,即便如此,绕线后仍会残留不少问题,…

C++之nothrow

nothrow 是 C 中的一个关键字,用于改变 new 操作符的行为,使其在内存分配失败时不抛出异常,而是安静地返回一个空指针(nullptr)。这对于那些不希望或不能处理异常的代码片段特别有用。要使用 nothrow,你需要…

系统如何做好安全加固?

一、Windows系统 Windows系统出厂时,微软为了兼容性,默认并未对系统安全做严格的限制,因此还需要做一些基本的安全加固,方可防止黑客入侵。 1、系统补丁更新 为什么要更新系统补丁?很多人感觉漏洞更新没必要&#x…

CSS学习笔记之基础教程(一)

1、CSS语法 CSS 规则集(rule-set)由选择器和声明块组成: 选择器指向您需要设置样式的 HTML 元素。 声明块包含一条或多条用分号分隔的声明。 每条声明都包含一个 CSS 属性名称和一个值,以冒号分隔。 多条 CSS 声明用分号分隔…

OpenCV-基于累计直方图的中值滤波算法

作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 实现原理 基于累计直方图的中值滤波算法是一种图像处理技术,用于去除图像中的噪声。它利用了像素值的频数分布&#…

LeetCode:滑动窗口最大值

文章收录于LeetCode专栏 LeetCode地址 滑动窗口最大值 题目 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。   返回 滑动窗口中的最大值 。   示例 1…

ATA-2161高压放大器用途有哪些种类

高压放大器是一种电子设备,其主要功能是将输入信号放大到较高的电压水平,同时保持信号的形状和特性。这种设备在各种应用领域中都有重要作用,它的种类繁多,根据不同的用途可以分为多种类型。 1.医学领域 在医学设备中,…

当AI遇见现实:数智化时代的人类社会新图景

文章目录 一、数智化时代的机遇二、数智化时代的挑战三、如何适应数智化时代《图解数据智能》内容简介作者简介精彩书评目录精彩书摘强化学习什么是强化学习强化学习与监督学习的区别强化学习与无监督学习的区别 前言/序言 随着科技的日新月异,我们步入了一个前所未…

“A”分考试经验分享:云计算HCIE考试请注意这几点...

大家好,我是誉天云计算HCIE的王同学,于4月2日"A"分通过了云计算3.0 HCIE的认证考试。 首先感谢誉天教育对我的辅导,感谢苗苗老师和石老师对我的帮助,通过这次考试让我对华为云计算有了一定的了解。接下来我就与大家分享…

创意无限,批量剪辑技巧:视频剪辑中的画中画技巧大揭秘

在视频剪辑的世界里,创意是无限的,而技巧则是实现这些创意的关键。画中画技巧作为视频剪辑中的一种高级技术,可以带给观众新颖的视觉体验,提升视频的质量和观赏性。本文将深入探讨批量剪辑中的画中画技巧,揭示其背后的…

css--控制滚动条的显示位置

各种学习后的知识点整理归纳,非原创! ① direction属性 滚动条在左侧显示② transform:scaleY() 滚动条在上侧显示 正常的滚动条会在内容超出规定的范围后在区域右侧和下侧显示在有些不正常的需求下会希望滚动条在上侧和左侧显示自己没有想到好的解决方案…

探索淘宝API接口对接(属性规格丨sku价格丨详情图丨优惠券等):打造智能电商解决方案

一、引言 随着电子商务的快速发展,越来越多的企业和开发者希望通过自动化和智能化的方式接入电商平台,以实现更高效的数据交互和业务流程。淘宝作为中国最大的电商平台之一,其提供的API接口成为了众多企业和开发者关注的焦点。本文将探讨淘宝…

竖线 竖杠 | before 伪类 文字前面的竖线跟文字对齐 只能用定位

<div class"sub-title">招租相关信息</div>.sub-title {font-size: 16px;text-align: left;color: #314790;font-weight: 700;position: relative;padding-left: 10px;margin-bottom: 20px; }.sub-title::before {content: "";background-colo…

LeetCode135:分发糖果

题目描述 n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求&#xff0c;给这些孩子分发糖果&#xff1a; 每个孩子至少分配到 1 个糖果。 相邻两个孩子评分更高的孩子会获得更多的糖果。 请你给每个孩子分发糖果&#xff0c;计算并返回需…

基于GEE遥感影像处理和长时序土地分类以及生物量估算分析

简介 Google Earth Engine云平台是目前全球范围内测绘领域内使用最为广泛的遥感云计算平台&#xff0c;其凭借强大的数据存储和云计算能力&#xff0c;极大了提高了全球科研工作者的科研产出&#xff0c;每年借助GEE平台发布的各类期刊论文超1000篇&#xff0c;在海量遥感数据的…

mySQL (基础面试)实物四属性 ACID属性,以及开启事务

mySQL具备四个基本属性 原子性atomicity 事务是一个完整的操作&#xff0c;事务的各个步骤是不可分的&#xff08;原子的&#xff09;&#xff0c;要么执行要么不执行 一致性consistency 当事务完成时&#xff0c;数据处于一致状态 隔离性isolation 并发事物之间彼此隔离…