前言
臭宝们,在学会上一节的基础知识之后,我们来实战一下。
预备知识
我们需要用到的知识点有:
- Column组件
- Row组件
- @Link装饰器
- button组件
- TextInput组件
- @State装饰器
最终效果图
代码实现
index页面(首页)
/**
* @program:
*
* @description:
*
*
* @author: 槐月
*
* @create: 2025/4/9-21:11
**/
//import用来引入组件。
import {button_Item}from '../Item/button_Item'
@Entry
@Component
struct Index {
//fontTitleSize和fontSubTitleSize是用来控制字体大小的。
@State fontTitleSize:number = 35;
@State fontSubTitleSize:number = 15;
//TitleInput和SubInput是用来控制输入框的。
@State TitleInput:string ='0';
@State SubInput:string = '';
build() {
Column(){
Column(){
TextInput({text:this.TitleInput.toString()})
.copyOption(CopyOptions.None)
.minFontSize(5)
.maxFontSize(this.fontTitleSize)
.enabled(false)//禁用输入框
.textOverflow(100)
.textAlign(TextAlign.End)
.backgroundColor('#75878a')
TextInput({text:this.SubInput})
.enabled(false)
.minFontSize(5)
.maxFontSize(this.fontSubTitleSize)
.backgroundColor('#75878a')
.textAlign(TextAlign.End)
}
.justifyContent(FlexAlign.End)
.backgroundColor('#75878a')
.margin({
top:20,
bottom:140
})
.padding({
right:5
})
.border({
width:2,
color:Color.White
})
.borderRadius(10)
.height('20%')
.alignItems(HorizontalAlign.End)
.width('90%')
button_Item({fontTopItem:this.fontTitleSize,
fontEndItem:this.fontSubTitleSize,
currentInput:this.TitleInput,previousValueString:this.SubInput})
}
.backgroundColor('#c0c6c9')
.width('100%')
.height('100%')
}
}
在上面这段代码中,我们使用了Column组件来布局。在Column里面我们又嵌套了一个Column用来放置输入框和按钮。fontTitleSize和fontSubTitleSize是用来控制字体大小的。TitleInput和SubInput是用来控制输入框的。
在Column中内嵌的Column做了以下设置:
- borderRadius(10)是为了让输入框的边框圆角更加明显。
- height(‘20%’)是为了让输入框的高度占整个页面的20%。
- width(‘90%’)是为了让输入框的宽度占整个页面的90%。
- alignItems(HorizontalAlign.End)是为了让输入框的内容向右对齐。
- justifyContent(FlexAlign.End)是为了让输入框的内容向下对齐。
- padding({right:5})是为了让输入框的内容向右偏移。
- margin({top:20,bottom:140})是为了让输入框的内容向下偏移。
- border({width:2,color:Color.White})是为了让输入框的边框更加明显,并且颜色为白色。
- backgroundColor(‘#75878a’)是为了让输入框的背景色为灰色。
- button_Item组件是用来放置按钮的。
- 在button_Item组件中,我们使用了@link装饰器来传递参数。
在textInput组件中,我们使用了@State装饰器来控制输入框的内容。对于textInput组件,我们使用了以下设置:
- textOverflow(100)是为了让输入框的内容超出部分不显示。
- copyOption(CopyOptions.None)是为了禁止复制输入框的内容。
- minFontSize(5)是为了让输入框的最小字体大小为5。
- maxFontSize(this.fontTitleSize)是为了让输入框的最大字体大小为我们定义的变量。
- textAlign(TextAlign.End)是为了让输入框的内容向右对齐。
- backgroundColor(‘#75878a’)是为了让输入框的背景色为灰色。
button_Item组件
import { trustedAppService } from "@kit.DeviceSecurityKit";
/**
* @program:
*
* @description:
*
* @author: 槐月
*
* @create: 2025/4/9-21:11
**/
@Extend(Button) function ButtonStatus(){
.fontSize(20)
.width('23%')
.height('10%')
.border({
width:1,
color:Color.Black
})
.type(ButtonType.Normal)
.borderRadius(5)
.margin({
top:3,
right:3,
left:3,
bottom:3
})
}
@Component
export struct button_Item {
//字体
@Link fontTopItem:number;
//字体
@Link fontEndItem:number;
//内容
@Link currentInput:string ;
//内容
@Link previousValueString:string;
//控制
@State hasNewNumber :boolean = true;
//控制输入
@State againInput:boolean = true;
//对数据进行操作
onClickButton(data:string){
switch (data) {
case 'C':
this.currentInput = '0';
this.previousValueString='';
this.ConvertFontSize(data)
break;
case 'DEL':
if (this.currentInput.length > 1) {
this.currentInput = this.currentInput.slice(0, -1);
} else {
this.currentInput = '0';
}
this.ConvertFontSize(data)
break;
case '=':
this.ConvertFontSize(data);
this.StringIntoArray();
this.againInput = false;
break;
default:
if (this.currentInput.length === 1 && this.currentInput.toString() === "0") {
this.currentInput = '';
}
if (!this.againInput) {
this.currentInput = '';
this.previousValueString = '';
this.againInput = true;
}
this.currentInput += data;
this.ConvertFontSize(data)
}
}
//拆解字符串
StringIntoArray(){
let charArray = this.currentInput.split("");
//结果
let result1 = '';
let result2 ='';
let sum= 0;
charArray.forEach((value,index,array)=>{
//中缀转后缀
try {
switch (value){
case 'x':
for (let i = 0; i < index; i++) {
result1+=array[i];
}
for (let j =index+1 ; j < array.length; j++) {
result2+=array[j];
}
sum = Number(result1)*Number(result2);
break;
case '/':
for (let i = 0; i < index; i++) {
result1+=array[i];
}
for (let j =index+1 ; j < array.length; j++) {
result2+=array[j];
}
sum = Number(result1)/Number(result2);
break;
case '-':
for (let i = 0; i < index; i++) {
result1+=array[i];
}
for (let j =index+1 ; j < array.length; j++) {
result2+=array[j];
}
sum = Number(result1)-Number(result2);
break;
case '+':
for (let i = 0; i < index; i++) {
result1+=array[i];
}
for (let j =index+1 ; j < array.length; j++) {
result2+=array[j];
}
sum = Number(result1)+Number(result2);
break;
}
}catch (e) {
}
})
this.previousValueString = sum.toString();
console.info(`${sum}`);
}
//大小写转换
ConvertFontSize(data:string){
switch (data){
case '=':
if(this.hasNewNumber){
let Temp = this.fontTopItem;
this.fontTopItem = this.fontEndItem;
this.fontEndItem = Temp;
this.hasNewNumber=false;
}
break;
default :
if(!this.hasNewNumber){
let Temp = this.fontTopItem;
this.fontTopItem = this.fontEndItem;
this.fontEndItem = Temp;
this.hasNewNumber = true;
}
}
}
build() {
Column(){
Row(){
//清除键位
Button('C')
.fontColor('#ee7800')
.backgroundColor('#75878a')
.ButtonStatus()
.onClick(()=>{
this.onClickButton('C')
})
//删除
Button('DEL')
.fontColor(Color.Black)
.backgroundColor('#75878a')
.ButtonStatus()
.onClick(()=>{
this.onClickButton('DEL');
})
Button('/')
.fontColor(Color.Black)
.backgroundColor('#75878a')
.ButtonStatus()
.onClick(()=>{
this.onClickButton('/')
// this.currentInput = this.computerResult.toString();
})
Button('x')
.fontColor(Color.Black)
.backgroundColor('#75878a')
.ButtonStatus()
.onClick(()=>{
this.onClickButton('x')
})
}
.justifyContent(FlexAlign.SpaceAround)
Row(){
Button('7')
.fontColor(Color.Black)
.backgroundColor('#f3f3f3')
.ButtonStatus()
.onClick(()=>{
this.onClickButton('7')
})
Button('8')
.fontColor(Color.Black)
.backgroundColor('#f3f3f3')
.ButtonStatus()
.onClick(()=>{
this.onClickButton('8')
})
Button('9')
.fontColor(Color.Black)
.backgroundColor('#f3f3f3')
.ButtonStatus()
.onClick(()=>{
this.onClickButton('9')
})
Button('-')
.fontColor(Color.Black)
.backgroundColor('#75878a')
.ButtonStatus()
.onClick(()=>{
this.onClickButton('-')
})
}
.justifyContent(FlexAlign.SpaceAround)
Row(){
Button('4')
.fontColor(Color.Black)
.backgroundColor('#f3f3f3')
.ButtonStatus()
.onClick(()=>{
this.onClickButton('4')
})
Button('5')
.fontColor(Color.Black)
.backgroundColor('#f3f3f3')
.ButtonStatus()
.onClick(()=>{
this.onClickButton('5')
})
Button('6')
.fontColor(Color.Black)
.backgroundColor('#f3f3f3')
.ButtonStatus()
.onClick(()=>{
this.onClickButton('6')
})
Button('+')
.backgroundColor('#75878a')
.fontColor(Color.Black)
.ButtonStatus()
.onClick(()=>{
this.onClickButton('+')
})
}
.justifyContent(FlexAlign.SpaceAround)
Row(){
Column(){
Row(){
Button('1')
.fontSize(20)
.border({
width:1,
color:Color.Black
})
.fontColor(Color.Black)
.backgroundColor('#f3f3f3')
.width('30%')
.height('10%')
.type(ButtonType.Normal)
.borderRadius(5)
.margin({
top:3,
right:3,
left:3
})
.onClick(()=>{
this.onClickButton('1')
})
Button('2')
.fontSize(20)
.border({
width:1,
color:Color.Black
})
.fontColor(Color.Black)
.backgroundColor('#f3f3f3')
.width('30%')
.height('10%')
.type(ButtonType.Normal)
.borderRadius(5)
.margin({
top:3,
right:3,
left:3
})
.onClick(()=>{
this.onClickButton('2')
})
Button('3')
.fontSize(20)
.border({
width:1,
color:Color.Black
})
.fontColor(Color.Black)
.backgroundColor('#f3f3f3')
.width('30%')
.height('10%')
.type(ButtonType.Normal)
.borderRadius(5)
.margin({
top:3,
right:3,
left:3
})
.onClick(()=>{
this.onClickButton('3')
})
}
.justifyContent(FlexAlign.SpaceAround)
Row(){
Button('0')
.fontSize(20)
.border({
width:1,
color:Color.Black
})
.fontColor(Color.Black)
.backgroundColor('#f3f3f3')
.width('63%')
.height('10%')
.type(ButtonType.Normal)
.borderRadius(5)
.margin({
top:3,
right:3,
left:3
})
.onClick(()=>{
this.onClickButton('0')
})
Button('.')
.fontSize(20)
.border({
width:1,
color:Color.Black
})
.fontColor(Color.Black)
.backgroundColor('#f3f3f3')
.width('30%')
.height('10%')
.type(ButtonType.Normal)
.borderRadius(5) .margin({
top:3,
right:3,
left:3
})
.onClick(()=>{
this.onClickButton('.')
})
}
}
.width('76%')
Button('=')
.fontSize(20)
.backgroundColor('#ee7800')
.width('22.5%')
.height('20%')
.borderRadius(5)
.type(ButtonType.Normal)
.margin({
top:3,
left:0,
right:3
})
.onClick(()=>{
this.onClickButton('=')
})
}
.width('100%')
}
.width('90%')
}
}
在这个代码片段中,我使用了Button()
方法来创建按钮,并为每个按钮设置了不同的样式和事件处理函数。例如,我为数字按钮设置了一个点击事件处理器来更新计算器的输入值,为操作符按钮(如加号、减号等)也设置了相应的事件处理器,并为等号按钮设置了计算结果的事件处理器:
- onClickButton方法用于处理按钮点击事件,根据不同的操作更新计算器的状态。例如,当用户点击数字或运算符时,该方法会被调用以更新当前输入的表达式和显示的结果。
- StringIntoArray方法用于将字符串表达式拆分为数组,以便于后续的计算处理。例如,当用户点击等号时,该方法会被调用以解析输入的数学表达式并计算结果。
- ConvertFontSize方法用于根据屏幕宽度动态调整字体大小,以适应不同设备的显示需求。例如,在计算器界面中,该方法可以根据设备屏幕的尺寸来调整按钮和文本的大小,确保用户在不同大小的屏幕上都能舒适地使用应用。
这样一来,用户就可以通过点击按钮来输入数学表达式并得到计算结果了。例如,当用户在屏幕上依次点击数字7、加号(+
)、数字5和等号(=
)时,应用会显示12的结果。
最终,这段代码实现了基本的计算器功能,用户可以通过点击按钮来输入数学表达式并得到结果。
我已经把源码上传到Gitee仓库了,搜索harmony-os-calculator,即可找到。
臭宝们,快来试试看这个计算器吧!😄