Android——一个神奇的计算器APP

article/2025/11/2 9:34:50

一个神奇的计算器APP

  • 中缀运算
    • 效果视频
      • 自定义圆形TextView
        • 效果图
        • 建立attr文件
        • 绘制圆形
      • 字符拼接
        • 清空栈内元素
      • 运算执行
        • 手势监听
        • 入栈&&出栈
        • 运算结果
        • 小数位判断
        • 运算代码
  • 任意进制转换
    • 效果视频
      • 进制转换
      • 结果逆置
      • 结果返回

中缀运算

        中缀运算定义了两个栈,数字栈和符号栈;分别存储用户输入的数字(例如:1,2,3)和输入的符号(例如:+,-);
        下列视频以1+2+3/2*3%3为例;首先输入1,然后输入+,通过对运算符点击事件监听,将其分别纳入数字栈和符号栈,然后在输入2和+,即对+进行监听,并取出符号栈栈顶元素,判断其是否为初始化元素,若为否,则将数字栈栈顶元素取出,并获取拼接字符作为另外一个运算数字;(数字栈栈顶元素 &(代表符号栈栈顶元素)拼接字符串)(1+2);得到结果3之后将其压入数字栈中,并将第二个+号压入符号栈,用于下次运算;以此类推…

效果视频

运算

自定义圆形TextView

效果图

在这里插入图片描述

建立attr文件

通过对控件手势动作进行监听,改变按钮的样式;即按下为白色,松开为橙色

<resources><declare-styleable name="SetCircle"><attr name="CircleColor" format="color"/><attr name="SelectCircle" format="color"/></declare-styleable>
</resources>

绘制圆形

protected void onDraw(Canvas canvas) {//判断手势动作,改变控件状态if (isSelect){CirclePaint.setColor( SelectCircle );}else {CirclePaint.setColor( CircleColor );}//设置填充方式CirclePaint.setStyle( Paint.Style.FILL );//设置抗锯齿CirclePaint.setAntiAlias( true );RectF rectF = new RectF();//设置半径,比较长宽,取最大值int radius = getMeasuredWidth() > getMeasuredHeight() ? getMeasuredWidth() : getMeasuredHeight();rectF.set(getPaddingLeft(),getPaddingTop(),radius-getPaddingRight(),radius-getPaddingBottom());//绘制圆弧canvas.drawArc(rectF,0,360,false,CirclePaint);super.onDraw(canvas);}

字符拼接

通过StringBuilder将用户输入的数字进行拼接,段尾对复位按钮进行判断,将数字栈和符号栈以及拼接字符串的内容全部清空;

private class NumOnClick implements View.OnClickListener{@Overridepublic void onClick(View view) {switch (view.getId()){case R.id.Zero:numBuilder.append('0');break;case R.id.One:numBuilder.append('1');break;case R.id.Two:numBuilder.append('2');break;case R.id.Three:numBuilder.append('3');break;case R.id.Four:numBuilder.append('4');break;case R.id.Five:numBuilder.append('5');break;case R.id.Six:numBuilder.append('6');break;case R.id.Seven:numBuilder.append('7');break;case R.id.Eight:numBuilder.append('8');break;case R.id.Nine:numBuilder.append('9');break;case R.id.Point:numBuilder.append('.');break;case R.id.Reset:isReset = true;}if (isReset){PopStack();numBuilder.delete(0,numBuilder.length());ResultBox.setText("0");operatorStack.push('#');isReset = false;}else {ResultBox.setText(numBuilder.toString());}}}

清空栈内元素

清空数字栈和符号栈内元素

  private void PopStack(){while (numStack.isEmpty()){numStack.pop();}while (operatorStack.isEmpty()){operatorStack.pop();}}

运算执行

手势监听

此处以加运算符为例,对按下和松开两个事情进行监听,分别改变控件样式,并传入相应运算符进行运算

   private class OperatorOnClick implements View.OnTouchListener{@Overridepublic boolean onTouch(View view, MotionEvent motionEvent) {boolean isPress = false;if (motionEvent.getAction() == MotionEvent.ACTION_DOWN){isPress = true;}switch (view.getId()){case R.id.Add:if (isPress){mAdd.IsSelect(true);mAdd.setTextColor(getResources().getColor(R.color.normal));StartOperation(ADD);}else {mAdd.IsSelect(false);mAdd.setTextColor(getResources().getColor(R.color.select));}break;

入栈&&出栈

在初始化时,将符号栈压入‘#’符号,即代表第一次执行,不进行结果运算

operatorStack.push('#');

    第一次运行时,即将符号栈栈顶元素取出,即‘#’,假如输入1和+,此时无法构成算式,因为确实另外一个运算数,即直接将其压入栈中,不进行结果运算;然后将拼接字符串清空,因为假如输入完了100和+,因为+号是不显示在用户界面的,如果不进行清空,之后输入的字符会追加在其之后,例如在输入50,即不清空为10050,会造成用户体验不良以及使用麻烦等缺点;
  假如输入了100和+,然后输入50和-,构成100+50-算式,第一次不进行运算,如上释所示,第二次输入的-,即取出符号栈顶元素+,和运算数100和50,并将其传入EXEOperation()方法,开始运算结果

   private void StartOperation(char symbol){char operator = operatorStack.pop();if (operator == EQUAL){operatorStack.push(symbol);} else if (operator == '#'){numStack.push(numBuilder.toString().isEmpty()?0:Double.parseDouble(numBuilder.toString()));operatorStack.push(symbol);numBuilder.delete(0,numBuilder.length());}else {switch (operator){case ADD:EXEOperation(numStack.pop(),numBuilder.toString().isEmpty()?0:Double.parseDouble(numBuilder.toString()),ADD);break;case SUB:EXEOperation(numStack.pop(),numBuilder.toString().isEmpty()?0:Double.parseDouble(numBuilder.toString()),SUB);break;case MULTIPLY:EXEOperation(numStack.pop(),numBuilder.toString().isEmpty()?0:Double.parseDouble(numBuilder.toString()),MULTIPLY);break;case DIVISION:EXEOperation(numStack.pop(),numBuilder.toString().isEmpty()?0:Double.parseDouble(numBuilder.toString()),DIVISION);break;case MOD:EXEOperation(numStack.pop(),numBuilder.toString().isEmpty()?0:Double.parseDouble(numBuilder.toString()),MOD);break;case EQUAL:EXEOperation(numStack.pop(),numBuilder.toString().isEmpty()?0:Double.parseDouble(numBuilder.toString()));break;}}}

运算结果

  三个参数分别为第一个运算数,和另外一个运算数,以及符号栈栈顶元素,对符号进行判断,并进行结果运算,然后将结果压入栈中以及第二个运算符压人符合栈;
  重点在于对等于键进行判断:
    1:例如输入算式1+1-,对第二个运算符进行监听即可得到前一结果,然后在输入数字,符号,得到前一结果…
    2:例如输入算式1+1=,此时并没有对等于符号进行监听,无法完成运算,解决办法为不将等于压入符号栈,直接结果入栈,相当于需要执行第一步才能完成运算

小数位判断

对结果字符串进行子串截取,判断小数点之后是否存在小数位,因为为double类型,默认会存在小数位。例如:
(1)1.0,则省略小数点后的0,直接输出0;
(2)1.05,则不进行小数位省略,直接输出

 //判断小数位之后是否有数字if (str.substring(str.indexOf('.') + 1, str.length() - 1).isEmpty()) {str = str.substring(0, str.indexOf('.'));}

运算代码

    private void EXEOperation(double front,double rear,char operator) {double result = 0;String str;/*** 对连续点击运算符,而运算数字并未符合标准时进行判断* 例如:12+* 此时12和+分别进栈,此时若再点击运算符+,则无法进行运算,因为rear运算数为空*/switch (operator) {case ADD:result = front + rear;break;case SUB:result = front - rear;break;case MULTIPLY:result = front * rear;break;case DIVISION:result = front / rear;break;case MOD:result = front < rear ? front :front % rear;break;}numStack.push(result);if (isReturn){operatorStack.push(EQUAL);}else {operatorStack.push(operator);isReturn = false;}str = String.valueOf(result);//判断小数位之后是否有数字if (str.substring(str.indexOf('.') + 1, str.length() - 1).isEmpty()) {str = str.substring(0, str.indexOf('.'));}ResultBox.setText(str);//前运算符清空,为后运算符输入做准备numBuilder.delete(0,numBuilder.length());}

任意进制转换

通过输入十进制数,分别转化为相应的二进制,八进制,十六进制数

效果视频

转换进制

进制转换

因为需要分别转化多个进制,无法对其数组长度进行判断,即将每个数字首元素作为存储数组长度的地址

   private int[] Conversion(int num,int binary){int[] remainder = new int[255];int count = 1;do {remainder[count++] = num%binary;num /= binary;} while (num != 0);remainder[0] = count;return remainder;}

结果逆置

通过对解析的进制数组进行逆置,因为十六进制的10——A,11——B…,所以需要对其进行判断,然后使用字符串拼接,最终返回一个结果字符串

    private String Inversion(int[] array){StringBuilder builder = new StringBuilder();for (int i = array[0]-1; i >=1 ; i--) {if (array[i] == 10){builder.append("A");}else if (array[i] == 11){builder.append("B");}else if (array[i] == 12){builder.append("C");}else if (array[i] == 13){builder.append("D");}else if (array[i] == 14){builder.append("E");}else if (array[i] == 15){builder.append("F");}else {builder.append(array[i]);}}return builder.toString();}

结果返回

int num = Integer.parseInt(ResultBox.getText().toString());
Binary_2.setText(Inversion(Conversion(num,2)));
Binary_8.setText(Inversion(Conversion(num,8)));
Binary_10.setText(Inversion(Conversion(num,10)));
Binary_16.setText(Inversion(Conversion(num,16)));

http://chatgpt.dhexx.cn/article/e0bcpLkv.shtml

相关文章

【Android】简易计算器

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 Android简易计算器 前言一、Kotlin版本1. activity_main.xml2. MainActivity.kt 二、Java版本1. activity_main.xml2. MainActivity.java 总结 前言 提示&#xff1a;Kotlin…

Android 计算器

Android 计算器 开发环境&#xff1a;android stdio 3.6.1 最终效果&#xff1a; 竖屏&#xff1a; 横屏&#xff1a; 完整项目&#xff1a;百度网盘链接 密码 v89n 主要代码&#xff1a; MainActivity.java: package com.example.experience_two;import androidx.appc…

android计算器

1、效果预览 2、项目布局 3、main.xml文件内容 <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"android:layout_width"fill_parent"android:layout_height"fi…

Android计算器简单实现及代码分析

一、UI布局及代码 页面效果 布局代码 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"…

Android计算器——入门

Android计算器—入门 作者&#xff1a;黑衣侠客 一.前言 这是我写的第一个App&#xff0c;利用的是《安卓第一行代码》第三章&#xff0c;UI控件的一些知识&#xff0c;然后整体结构综合了一些CSDN博客和简书上的一些著作&#xff0c;同样&#xff0c;在写Android计算器&…

基础复习——项目练习——计算器

布局&#xff1a; <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:background"#eeeeee"android:orientation"vert…

安卓-AndroidStudio-计算器

安卓--Android Studio--简易计算器 结果截图关键代码讲解完整代码 本人是一名在校学生&#xff0c;由于上个学期的课程内容包括移动开发&#xff0c;其中的实验也算是大部分是自己完成的&#xff0c;所以算是写博客记录一下吧。 第一次写&#xff0c;有啥问题及时交流哈&#x…

Django数据库操作

目录 一、Django/ORM框架介绍及配置 1.1、ORM框架介绍 1.2、Django数据库配置 二、定义模型类数 2.1、定义模型类 2.2、迁移 2.3、插入数据 三、单表据库操作(增、删、改、查) 3.1、增 3.2、删 3.3、改 3.4查&#xff08;重点&#xff09; 四、两表联查 4.1、一对…

Qt入门------数据库操作

文章目录 一、数据库1.数据库驱动2.查询驱动3.连接数据库4.执行sql语句5.插入数据6.事务 二 &#xff0c;sql模型类1.QSqlQueryModel模型2.QSqlTableModel模型3.QSqlRelationalTableModel模型 一、数据库 Qt中的Qt SQL模块提供了对数据库的支持&#xff0c;模块中类可分为三层…

Java的数据库操作

Java的数据库操作&#xff0c;上学期末的课设是用到的&#xff0c;然而老师把JDBC连接mysql数据库的代码和配置文件已经给好了&#xff0c;那时对它可以说是只有一点点印象。 今天跟着书走一边敲一边&#xff0c;总算是有所进步。 数据库表的创建和初始数据的操作&#xff0c…

一文详解python中的数据库操作

python中的数据库操作 一、数据库编程接口1. 连接对象 二、使用内置的SQLite1.创建数据库文件2.操作SQLite 三、MySql数据库的使用3.1 安装MySql3.2 设置环境变量3.3 启动MySql3.4 使用navicat for mysql 管理软件3.5 安装PyMysql模块3.6 连接数据库 四、创建数据表4.1 创建boo…

数据库操作练习题

如何查看员工表中的所有字段&#xff1f; 如何查看员工表中的姓名和性别&#xff1f; 如何知道每个员工一年的总收入&#xff1f; 怎么查看女员工的信息&#xff1f; 如何查看月薪范围位于 8000 到 12000 之间的员工&#xff1f; 查询员工中叫做“张三”、“李四” 或“张飞”的…

MySQL(一)数据库操作

1.关系型数据库与非关系型数据库区别与联系 1.关系型数据库 ( SQL ) MySQL , Oracle , SQL Server , SQLite , DB2 , … 关系型数据库通过外键关联来建立表与表之间的关系 2.非关系型数据库 ( NOSQL ) Redis , MongoDB , … 非关系型数据库通常指数据以对象的形式存储在数据…

使用ORACLE 进行数据库操作

上一期讲了 如何创建表&#xff0c;例如我们创建了一个 名为 t_customer 的表&#xff0c;格式为下&#xff1a; create table t_customer(cust_id int primary key,cust_name varchar(20),cust_gender char(3),cust_age int,cust_birthday date,cust_height number(3,2),cust…

C#数据库操作

功能需求 1&#xff0c;利用随机数模拟产生每次考试成绩 2&#xff0c;将每次考试成绩存入到数据库 3&#xff0c;将每次考试成绩划分优、良、中、差、不及格五类&#xff0c;并作为查询条件&#xff0c;查询符合每种水平的成绩 技术知识点 1.random类的使用 2.数据库的链…

云数据库操作

1 云数据库创建 每一个list就相当于一个表&#xff0c;每个记录就是一条内容 云数据库存储形式是JSON2 读取云数据库值 数据库初始化 const db wx.cloud.database() 连接数据库 db.collection(需要连接的数据列表名)可以通过.doc(‘具体id号’)获取具体的信息内容获取年、月…

Android数据库操作

Android内置了一个名为SQLite的关系型数据库&#xff0c;这是一款轻量型的数据库&#xff0c;操作十分简便。SQLite与别的数据库不同的是&#xff0c;它没有数据类型。可以保存任何类型的数据到你所想要保存的任何表的任何列中。但它又支持常见的类型比如: NULL, VARCHAR, TEXT…

数据库基本操作

一、数据库基本操作 1.数据库的基本操作 -- 1.数据库的基本操作 使用test数据库 USE test; -- 查看当前test数据库中所有表 MySQL命令 SHOW TABLES; -- 查表的基本信息 SHOW CREATE TABLE student; -- -- 查看表的字段信息 desc student; 2.数据表的基本操作 -- 2.数据表的…

数据库基础操作

一、数据库的操作 数据库与客户端是通过网络进行交互的。 1、显示当前数据库 sql语句必须以 ; 结尾 show databases; 2、创建数据库 create database 数据库名; ->如果数据库sql敲错了&#xff0c;会有提示。 ->如果sql敲错了&#xff0c;可以按 ctrlc来终止sql。…

数据库的基本操作

目录 一、数据库的基本操作 1、数据库的登录及退出 2、查看所有数据库 3、显示数据库版本 4、显示时间 5、创建数据库 6、查看创建数据库的语句 7、查看当前使用的数据库 8、查看当前用户 9、使用某个数据库 10、删除数据库 二、数据表的基本操作 1、查看当前数据…