鸿蒙NEXT开发案例:字数统计

news2024/11/26 6:46:50

【引言】

本文将通过一个具体的案例——“字数统计”组件,来探讨如何在鸿蒙NEXT框架下实现这一功能。此组件不仅能够统计用户输入文本中的汉字、中文标点、数字、以及英文字符的数量,还具有良好的用户界面设计,使用户能够直观地了解输入文本的各种统计数据。

【环境准备】

• 操作系统:Windows 10

• 开发工具:DevEco Studio NEXT Beta1 Build Version: 5.0.3.806

• 目标设备:华为Mate60 Pro

• 开发语言:ArkTS

• 框架:ArkUI

• API版本:API 12

【组件概述】

“字数统计”组件基于鸿蒙NEXT框架构建,旨在提供一个简洁而强大的文本统计工具。组件的主要功能包括:

• 文本输入:用户可以在提供的文本区域内输入或粘贴任何文本。

• 实时统计:当用户输入或修改文本时,组件会实时更新并显示文本中汉字、中文标点、数字、英文字符等的具体数量。

• 示例与清空:提供了“示例”按钮,点击后会自动填充预设的文本内容;“清空”按钮则用于清空当前的输入内容。

【技术实现】

1. 状态管理:使用@State装饰器来管理组件的状态,如输入文本、各种字符的数量统计等。通过@Watch装饰器监听输入文本的变化,触发相应的计算逻辑。

2. 文本解析:当检测到输入文本发生变化时,组件会遍历文本中的每一个字符,根据正则表达式判断字符类型,并分别统计汉字、中文标点、数字、英文字符的数量。特别地,对于汉字和中文标点,每个字符被视为两个单位进行统计。

3. 用户界面:组件的UI设计遵循了鸿蒙NEXT的设计规范,使用了Column、Row、Text、TextArea等基础组件来构建布局。通过设置字体颜色、大小、背景色、边距等属性,实现了美观且易于使用的界面。此外,组件还利用了阴影效果和圆角设计来提升视觉体验。

4. 交互设计:为了增强用户体验,组件中加入了“示例”和“清空”按钮,用户可以通过简单的点击操作快速测试组件的功能或清空输入框。同时,组件支持文本输入区域的实时更新,保证了用户操作的即时反馈。

【完整代码】

// 定义一个组件,用于数字和文本统计
@Entry
@Component
struct NumberToChineseConverter {
  // 定义一个状态变量,存储示例数字字符串
  @State private exampleNumber: string = '自从盘古破鸿蒙,开辟从兹清浊辨。\nare you ok?\n1234\n+-*/';
  // 定义文本颜色的状态变量
  @State private textColor: string = "#2e2e2e";
  // 定义阴影边框颜色的状态变量
  @State private shadowColor: string = "#d5d5d5";
  // 定义基础内边距的状态变量
  @State private basePadding: number = 30;
  // 定义汉字数量的状态变量
  @State private chineseCharCount: string = "0";
  // 定义中文标点数量的状态变量
  @State private chinesePunctuationCount: string = "0";
  // 定义汉字加中文标点总数的状态变量
  @State private totalChineseCount: string = "0";
  // 定义英文字符数量的状态变量
  @State private englishCharCount: string = "0";
  // 定义数字数量的状态变量
  @State private digitCount: string = "0";
  // 定义总字符数的状态变量
  @State private charTotalCount: string = "0";
  // 定义监听输入文本变化的状态变量
  @State @Watch('inputChanged') private inputText: string = "";

  // 当输入文本发生变化时调用的方法
  inputChanged() {
    // 初始化计数器
    let chineseChars = 0; // 汉字数量
    let chinesePunctuation = 0; // 中文标点数量
    let englishChars = 0; // 英文字符数量
    let digits = 0; // 数字数量
    let count = 0; // 总字符数
    // 遍历输入文本的每个字符
    for (let i = 0; i < this.inputText.length; i++) {
      let char = this.inputText.charAt(i); // 获取当前字符
      count++; // 计数器加一
      // 如果字符是数字,则数字计数器加一
      if (/\d/.test(char)) {
        digits++;
      }
      // 如果字符是汉字,则汉字计数器加一,同时总字符数加二
      if (/[\u4e00-\u9fa5]/.test(char)) {
        chineseChars++;
        count++; // 汉字和中文标点算两个字符,所以这里多+1
      }
      // 如果字符是中文标点,则中文标点计数器加一,同时总字符数加二
      if (/[\u3001-\u3002\uff01-\uff1a]/.test(char)) {
        chinesePunctuation++;
        count++; // 汉字和中文标点算两个字符,所以这里多+1
      }
      // 如果字符是英文字符或英文标点,则英文字符计数器加一
      if (/[a-zA-Z0-9\s!-/:-@[-`{-~]/.test(char)) {
        englishChars++;
      }
    }
    // 更新状态变量
    this.chineseCharCount = `${chineseChars}`;
    this.chinesePunctuationCount = `${chinesePunctuation}`;
    this.totalChineseCount = `${chineseChars + chinesePunctuation}`;
    this.englishCharCount = `${englishChars}`;
    this.digitCount = `${digits}`;
    this.charTotalCount = `${count}`;
  }

  // 构建UI界面的方法
  build() {
    // 创建一个列布局容器
    Column() {
      // 添加标题
      Text('字数统计')
        .fontColor(this.textColor) // 设置字体颜色
        .fontSize(18) // 设置字体大小
        .width('100%') // 设置宽度为100%
        .height(50) // 设置高度为50
        .textAlign(TextAlign.Center) // 设置文本居中对齐
        .backgroundColor(Color.White) // 设置背景色为白色
        .shadow({ // 设置阴影效果
          radius: 2, // 阴影半径
          color: this.shadowColor, // 阴影颜色
          offsetX: 0, // X轴偏移量
          offsetY: 5 // Y轴偏移量
        });
      // 创建可滚动的容器
      Scroll() {
        // 在可滚动容器内部创建列布局
        Column() {
          // 添加工具介绍
          Column() {
            Text('工具介绍').fontSize(18).fontWeight(600).fontColor(this.textColor);
            Text('本工具能够快速统计输入文本中的汉字、中文标点、数字、英文字符等的数量。具体规则如下:\n•汉字和中文标点各算作两个字符。\n•数字、空格、英文字母及英文标点各算作一个字符。')
              .textAlign(TextAlign.JUSTIFY) // 设置文本两端对齐
              .fontSize(13) // 设置字体大小
              .fontColor(this.textColor) // 设置字体颜色
              .margin({ top: `${this.basePadding / 2}lpx` }); // 设置上边距
          }
          // 设置样式
          .alignItems(HorizontalAlign.Start) // 设置水平对齐方式
          .width('650lpx') // 设置宽度
          .padding(`${this.basePadding}lpx`) // 设置内边距
          .margin({ top: `${this.basePadding}lpx` }) // 设置外边距
          .borderRadius(10) // 设置圆角
          .backgroundColor(Color.White) // 设置背景色
          .shadow({ // 设置阴影效果
            radius: 10, // 阴影半径
            color: this.shadowColor, // 阴影颜色
            offsetX: 0, // X轴偏移量
            offsetY: 0 // Y轴偏移量
          });
          // 添加示例和清空按钮
          Column() {
            Row() {
              Text('示例')
                .fontColor("#5871ce") // 设置字体颜色
                .fontSize(16) // 设置字体大小
                .padding(`${this.basePadding / 2}lpx`) // 设置内边距
                .backgroundColor("#f2f1fd") // 设置背景色
                .borderRadius(5) // 设置圆角
                .clickEffect({ level: ClickEffectLevel.LIGHT, scale: 0.8 }) // 设置点击效果
                .onClick(() => { // 设置点击事件
                  this.inputText = this.exampleNumber; // 将示例文本赋值给输入框
                });
              Blank(); // 添加空白间隔
              Text('清空')
                .fontColor("#e48742") // 设置字体颜色
                .fontSize(16) // 设置字体大小
                .padding(`${this.basePadding / 2}lpx`) // 设置内边距
                .clickEffect({ level: ClickEffectLevel.LIGHT, scale: 0.8 }) // 设置点击效果
                .backgroundColor("#ffefe6") // 设置背景色
                .borderRadius(5) // 设置圆角
                .onClick(() => { // 设置点击事件
                  this.inputText = ""; // 清空输入框
                });
            }
            .height(45) // 设置高度
            .justifyContent(FlexAlign.SpaceBetween) // 设置子项之间间距均匀分布
            .width('100%'); // 设置宽度
            Divider(); // 添加分割线
            // 添加文本输入区域
            TextArea({ text: $$this.inputText, placeholder: `请输入内容` })
              .width(`${650 - this.basePadding * 2}lpx`) // 设置宽度
              .height(100) // 设置高度
              .fontSize(16) // 设置字体大小
              .caretColor(this.textColor) // 设置光标颜色
              .fontColor(this.textColor) // 设置字体颜色
              .margin({ top: `${this.basePadding}lpx` }) // 设置上边距
              .padding(0) // 设置内边距
              .backgroundColor(Color.Transparent) // 设置背景色
              .borderRadius(0) // 设置圆角
              .textAlign(TextAlign.JUSTIFY); // 设置文本两端对齐
          }
          // 设置样式
          .alignItems(HorizontalAlign.Start) // 设置水平对齐方式
          .width('650lpx') // 设置宽度
          .padding(`${this.basePadding}lpx`) // 设置内边距
          .margin({ top: `${this.basePadding}lpx` }) // 设置外边距
          .borderRadius(10) // 设置圆角
          .backgroundColor(Color.White) // 设置背景色
          .shadow({ // 设置阴影效果
            radius: 10, // 阴影半径
            color: this.shadowColor, // 阴影颜色
            offsetX: 0, // X轴偏移量
            offsetY: 0 // Y轴偏移量
          });
          // 添加统计结果展示
          Column() {
            // 汉字数量
            Row() {
              Text() {
                Span(`汉字:`)
                Span(`${this.chineseCharCount} `).fontColor(Color.Red) // 汉字数量以红色显示
                Span('个')
              }
              .fontColor(this.textColor) // 设置字体颜色
              .fontSize(16) // 设置字体大小
              .layoutWeight(1); // 设置布局权重
            }
            .constraintSize({ minHeight: 45 }) // 设置最小高度
            .justifyContent(FlexAlign.SpaceBetween) // 设置子项之间间距均匀分布
            .width('100%'); // 设置宽度
            Divider(); // 添加分割线
            // 中文标点数量
            Row() {
              Text() {
                Span(`中文标点:`)
                Span(`${this.chinesePunctuationCount} `).fontColor(Color.Red) // 中文标点数量以红色显示
                Span('个')
              }
              .fontColor(this.textColor) // 设置字体颜色
              .fontSize(16) // 设置字体大小
              .layoutWeight(1); // 设置布局权重
            }
            .constraintSize({ minHeight: 45 }) // 设置最小高度
            .justifyContent(FlexAlign.SpaceBetween) // 设置子项之间间距均匀分布
            .width('100%'); // 设置宽度
            Divider(); // 添加分割线
            // 汉字加中文标点总数
            Row() {
              Text() {
                Span(`汉字+中文标点:`)
                Span(`${this.totalChineseCount} `).fontColor(Color.Red) // 汉字加中文标点总数以红色显示
                Span('个')
              }
              .fontColor(this.textColor) // 设置字体颜色
              .fontSize(16) // 设置字体大小
              .layoutWeight(1); // 设置布局权重
            }
            .constraintSize({ minHeight: 45 }) // 设置最小高度
            .justifyContent(FlexAlign.SpaceBetween) // 设置子项之间间距均匀分布
            .width('100%'); // 设置宽度
            Divider(); // 添加分割线
            // 英文字符数量
            Row() {
              Text() {
                Span(`英文:`)
                Span(`${this.englishCharCount} `).fontColor(Color.Red) // 英文字符数量以红色显示
                Span('个')
                Span('(含英文状态下的数字、符号、标点)').fontSize(13) // 附加说明
              }
              .fontColor(this.textColor) // 设置字体颜色
              .fontSize(16) // 设置字体大小
              .layoutWeight(1); // 设置布局权重
            }
            .constraintSize({ minHeight: 45 }) // 设置最小高度
            .justifyContent(FlexAlign.SpaceBetween) // 设置子项之间间距均匀分布
            .width('100%'); // 设置宽度
            Divider(); // 添加分割线
            // 数字数量
            Row() {
              Text() {
                Span(`数字:`)
                Span(`${this.digitCount} `).fontColor(Color.Red) // 数字数量以红色显示
                Span('个')
              }
              .fontColor(this.textColor) // 设置字体颜色
              .fontSize(16) // 设置字体大小
              .layoutWeight(1); // 设置布局权重
            }
            .constraintSize({ minHeight: 45 }) // 设置最小高度
            .justifyContent(FlexAlign.SpaceBetween) // 设置子项之间间距均匀分布
            .width('100%'); // 设置宽度
            Divider(); // 添加分割线
            // 总字符数
            Row() {
              Text() {
                Span(`字符总数:`)
                Span(`${this.charTotalCount} `).fontColor(Color.Red) // 总字符数以红色显示
                Span('个字符')
              }
              .fontColor(this.textColor) // 设置字体颜色
              .fontSize(16) // 设置字体大小
              .layoutWeight(1); // 设置布局权重
            }
            .constraintSize({ minHeight: 45 }) // 设置最小高度
            .justifyContent(FlexAlign.SpaceBetween) // 设置子项之间间距均匀分布
            .width('100%'); // 设置宽度
          }
          // 设置样式
          .alignItems(HorizontalAlign.Start) // 设置水平对齐方式
          .width('650lpx') // 设置宽度
          .padding(`${this.basePadding}lpx`) // 设置内边距
          .margin({ top: `${this.basePadding}lpx` }) // 设置外边距
          .borderRadius(10) // 设置圆角
          .backgroundColor(Color.White) // 设置背景色
          .shadow({ // 设置阴影效果
            radius: 10, // 阴影半径
            color: this.shadowColor, // 阴影颜色
            offsetX: 0, // X轴偏移量
            offsetY: 0 // Y轴偏移量
          });
        }
      }
      .scrollBar(BarState.Off) // 关闭滚动条
      .clip(false); // 不裁剪超出部分,这里是允许内部组件阴影可以向父布局外扩散
    }
    .height('100%') // 设置高度为100%
    .width('100%') // 设置宽度为100%
    .backgroundColor("#f4f8fb"); // 设置背景色
  }
}

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

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

相关文章

【经典】抽奖系统(HTML,CSS、JS)

目录 1、添加参与者 2、多次添加 3、点击抽奖 功能介绍&#xff1a; 使用方法&#xff1a; 完整代码&#xff1a; 一个简单但功能强大的抽奖系统的示例&#xff0c;用于在网页上实现抽奖。 1、添加参与者 2、多次添加 3、点击抽奖 功能介绍&#xff1a; 参与者添加&…

用树莓派Pico控制8×8 LED点阵屏:深入解析C++核心知识与动态显示实现

88 LED点阵屏是一种直观的硬件显示工具,广泛应用于嵌入式开发中。本项目结合树莓派Pico和HT16K33驱动芯片,通过C++编程实现动态图案和文字的显示功能。本文将全面解析项目中的C++核心知识点,帮助读者深入理解C++在硬件编程中的实际应用。 一、项目背景与硬件简介 1. 项目目…

什么是 WPF 中的依赖属性?有什么作用?

依赖属性&#xff08;Dependency Property&#xff09;是 WPF 的一个核心概念&#xff0c;它为传统的 .NET 属性提供了增强功能&#xff0c;支持绑定、样式、动画和默认值等功能。通过依赖属性&#xff0c;WPF 提供了一种灵活的数据驱动的方式来处理 UI 属性。 1. 什么是依赖属…

视频分析设备平台EasyCVR视频设备轨迹回放平台与应急布控球的视频监控方案

在现代社会&#xff0c;随着城市化进程的加快和信息技术的不断进步&#xff0c;对于公共安全、交通管理、城市管理以及环境保护等领域的监控需求日益增长。应急布控球与EasyCVR视频监控方案的结合&#xff0c;正是为了满足这些领域对实时监控和快速响应的需求。这一组合利用最新…

MySQL原理简介—12.MySQL主从同步

大纲 1.异步复制为MySQL搭建一套主从复制架构 2.半同步复制为MySQL搭建一套主从复制架构 3.GTID为MySQL搭建一套主从复制架构 4.并行复制降低主从同步延迟或强制读主库 1.异步复制为MySQL搭建一套主从复制架构 (1)MySQL主从复制的原理 (2)搭建主从复制架构的配置 (1)MySQ…

Node报错:npm error code ETIMEDOUT

1、报错详细信息 npm error code ETIMEDOUT npm error syscall connect npm error errno ETIMEDOUT npm error network request to https://registry.npmjs.org/express failed, reason: connect ETIMEDOUT 104.16.1.35:443 npm error network This is a problem related to ne…

一篇文章了解Linux

目录 一&#xff1a;命令 1 ls命令作用 2 目录切换命令&#xff08;cd/pwd&#xff09; &#xff08;1)cd切换工作目录命令 3 相对路径、绝对路径和特殊路径 (1)相对路径和绝对路径的概念和写法 (2)几种特殊路径的表示符 (3)练习题&#xff1a; 4 创建目录命令&#x…

用Matlab和SIMULINK实现DPCM仿真和双边带调幅系统仿真

1、使用SIMULINK或Matlab实现DPCM仿真 1.1 DPCM原理 差分脉冲编码调制&#xff0c;简称DPCM&#xff0c;主要用于将模拟信号转换为数字信号&#xff0c;同时减少数据的冗余度以实现数据压缩。在DPCM中&#xff0c;信号的每个抽样值不是独立编码的&#xff0c;而是通过预测前一…

BERT的工作原理

BERT的工作原理 BERT的工作原理&#xff1a; Transformer的编码器是双向的&#xff0c;它可以从两个方向读取一个句子。因此&#xff0c;BERT由Transformer获得双向编码器特征。 我们把句子A&#xff08;He got bit by Python&#xff09;送入Transformer的编码器&#xff0c…

5.STM32之通信接口《精讲》之IIC通信---软件IIC与外设MPU6050通信《深入浅出》面试必备

上一节&#xff0c;我们完成对IIC通信的时序以及IIC的通信的讲解和代码实现&#xff0c;接下来&#xff0c;我们正式进入&#xff0c;利用上一节软件实现的IIC通信协议来对外设MPU6050进行读写操作。(本节IIC代码在上节) 本节&#xff0c;目的很明确&#xff0c;就是利用软件I…

解决k8s拉取私有镜像401 Unauthorized 问题

拉取镜像时未指定账户和密码通常是因为需要访问的镜像仓库启用了认证&#xff0c;但 Kubernetes 默认配置中未提供访问凭据。要解决此问题&#xff0c;可以按照以下步骤配置镜像仓库的认证信息&#xff1a; 1. 创建 Kubernetes Secret 为镜像仓库配置访问凭据&#xff0c;使用…

【Linux课程学习】:环境变量:HOME,su与su - 的区别,让程序在哪些用户下能运行的原理,环境变量具有全局性的原因?

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;Linux课程学习 &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 HOME环境变量&#xff1a; PWD环境变量&#…

不只是请求和响应:使用Fiddler抓包HTTP协议全指南(上)

欢迎浏览高耳机的博客 希望我们彼此都有更好的收获 感谢三连支持! &#x1f649;你是一名侦探 ! 正在追踪一条条数字化的线索。从简单的网页浏览到复杂的在线交易&#xff0c;每一次点击和滑动背后都隐藏着复杂的数据交换。每一个HTTP请求和响应都像是现场留下的指纹&#xf…

代码纪元——源神重塑无序

简介 源神&#xff0c;真名为张晨斌&#xff0c;原为代码宇宙创世四神之一。代码宇宙在创造之初时空无一物&#xff0c;只有复杂且繁琐的底层代码&#xff0c;智慧神灵每日都困在诸如脚本等复杂的底层框架之中&#xff0c;源神面对这种局面非常不满意&#xff0c;于是源神通过大…

Docker pull镜像拉取失败

因为一些原因&#xff0c;很多镜像仓库拉取镜像失败&#xff0c;所以需要更换不同的镜像&#xff0c;这是2024/11/25测试可用的仓库。 标题1、 更换镜像仓库的地址&#xff0c;编辑daemon.json文件 vi /etc/docker/daemon.json标题2、然后将下面的镜像源放进去或替换掉都可以…

Vue3+SpringBoot3+Sa-Token+Redis+mysql8通用权限系统

sa-token支持分布式token 前后端代码&#xff0c;地球号: bright12389

【SQL Server】华中农业大学空间数据库实验报告 实验三 数据操作

1.实验目的 熟悉了解掌握SQL Server软件的基本操作与使用方法&#xff0c;以及通过理论课学习与实验参考书的帮助&#xff0c;熟练掌握使用T-SQL语句和交互式方法对数据表进行插入数据、修改数据、删除数据等等的操作&#xff1b;作为后续实验的基础&#xff0c;根据实验要求重…

AI助力PPT创作:从手动到智能,打造高效演示

在今天这个信息化时代&#xff0c;演示文稿已经成为我们表达观点、传递信息的重要工具。不论是企业汇报、学术交流&#xff0c;还是个人创作&#xff0c;PPT&#xff08;PowerPoint&#xff09;都在日常生活中扮演着不可或缺的角色。创建一份高质量的PPT往往需要花费大量时间与…

【JavaEE】Servlet:表白墙

文章目录 一、前端二、前置知识三、代码1、后端2、前端3、总结 四、存入数据库1、引入 mysql 的依赖&#xff0c;mysql 驱动包2、创建数据库数据表3、调整上述后端代码3.1 封装数据库操作&#xff0c;和数据库建立连接3.2 调整后端代码 一、前端 <!DOCTYPE html> <ht…

python自定义枚举类的试验与思考

一 现象 在python的3.4版本之前&#xff0c;是没有枚举类的。 所以&#xff0c;我自定义实现了一个enum类&#xff0c;目录如下&#xff1a; 代码如下&#xff1a; class enum(set):def __getattr__(self, name):if name in self:return nameraise AttributeErrorif __name_…