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

【引言】
本文将通过一个具体的案例——“字数统计”组件,来探讨如何在鸿蒙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. 交互设计:为了增强用户体验,组件中加入了“示例”和“清空”按钮,用户可以通过简单的点击操作快速测试组件的功能或清空输入框。同时,组件支持文本输入区域的实时更新,保证了用户操作的即时反馈。
【完整代码】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 | // 定义一个组件,用于数字和文本统计 @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" ); // 设置背景色 } } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!