【Android】控件与布局入门 - 简易计算器

目录

1. 基础开发环境

2. 计算器的布局和相关按钮

3. 计算器的主要运算逻辑

4. APK 文件

5. 项目源码


1. 基础开发环境

JDK:JDK17

Android Studio:Android Studio Giraffe | 2022.3.1

Android SDK:Android API 34

Gradle: gradle-8.0-bin.zip

2. 计算器的布局和相关按钮

使用 LinearLayout 和 GridLayout 实现计算器的交互前端。

layout 文件如下

<?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="match_parent"android:background="#EEEEEE"android:orientation="vertical"android:padding="5dp"><ScrollViewandroid:layout_width="match_parent"android:layout_height="wrap_content"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><TextViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:text="@string/simple_calculator"android:textColor="@color/black"android:textSize="20sp"/><TextViewandroid:id="@+id/tv_result"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@color/white"android:lines="3"android:text="@string/filler"android:gravity="end|bottom"android:textColor="@color/black"android:textSize="25sp"/><GridLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:columnCount="4"android:rowCount="5"><Buttonandroid:id="@+id/btn_clear_entry"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/cancel"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_divide"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/divide"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_multiply"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/multiply"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_clear"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/delete"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_seven"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/seven"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_eight"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/eight"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_nine"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/nine"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_plus"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/plus"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_four"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/four"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_five"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/five"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_six"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/six"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_minus"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/minus"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_one"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/one"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_two"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/two"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_three"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/three"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_sqrt"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/sqrt"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_reciprocal"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/reciprocal"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_zero"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/zero"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_dot"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/dot"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/><Buttonandroid:id="@+id/btn_equal"android:layout_width="0dp"android:layout_height="@dimen/button_height"android:layout_columnWeight="1"android:gravity="center"android:text="@string/equal"android:textColor="@color/black"android:textSize="@dimen/button_font_size"/></GridLayout></LinearLayout></ScrollView></LinearLayout>

相关 values 如下:

  • strings.xml
<resources><string name="app_name">calculator</string><string name="simple_calculator">计算器</string><string name="filler">0</string><string name="cancel">CE</string><string name="divide">÷</string><string name="multiply">×</string><string name="plus">+</string><string name="minus">-</string><string name="delete">C</string><string name="zero">0</string><string name="one">1</string><string name="two">2</string><string name="three">3</string><string name="four">4</string><string name="five">5</string><string name="six">6</string><string name="seven">7</string><string name="eight">8</string><string name="nine">9</string><string name="sqrt">√</string><string name="dot">.</string><string name="equal">=</string><string name="reciprocal">1/X</string>
</resources>
  • dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources><dimen name="button_font_size">30sp</dimen><dimen name="button_height">75dp</dimen>
</resources>

实际效果:

 

3. 计算器的主要运算逻辑

package com.example.calculator;import android.os.Bundle;
import android.view.View;
import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;import java.util.Arrays;
import java.util.List;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private TextView tvResult;private String firstNum = "";private String secondNum = "";private String operator = "";private String result = "";private String showText = "";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 从布局文件中获取文本视图tvResult = findViewById(R.id.tv_result);// 为所有按钮注册点击监听器findViewById(R.id.btn_clear_entry).setOnClickListener(this);findViewById(R.id.btn_divide).setOnClickListener(this);findViewById(R.id.btn_multiply).setOnClickListener(this);findViewById(R.id.btn_clear).setOnClickListener(this);findViewById(R.id.btn_seven).setOnClickListener(this);findViewById(R.id.btn_eight).setOnClickListener(this);findViewById(R.id.btn_nine).setOnClickListener(this);findViewById(R.id.btn_plus).setOnClickListener(this);findViewById(R.id.btn_four).setOnClickListener(this);findViewById(R.id.btn_five).setOnClickListener(this);findViewById(R.id.btn_six).setOnClickListener(this);findViewById(R.id.btn_minus).setOnClickListener(this);findViewById(R.id.btn_one).setOnClickListener(this);findViewById(R.id.btn_two).setOnClickListener(this);findViewById(R.id.btn_three).setOnClickListener(this);findViewById(R.id.btn_sqrt).setOnClickListener(this);findViewById(R.id.btn_reciprocal).setOnClickListener(this);findViewById(R.id.btn_zero).setOnClickListener(this);findViewById(R.id.btn_dot).setOnClickListener(this);findViewById(R.id.btn_equal).setOnClickListener(this);}@Overridepublic void onClick(View view) {String inputText = ((TextView) view).getText().toString();List<Integer> fourOperations = Arrays.asList(R.id.btn_plus, R.id.btn_minus, R.id.btn_multiply, R.id.btn_divide);int id = view.getId();if (id == R.id.btn_clear) {// 清除clear();} else if (id == R.id.btn_clear_entry) {// 清除输入clearEntryOperate();} else if (fourOperations.contains(id)) {operator = inputText;refreshShowText(showText + operator);// 四则运算} else if (id == R.id.btn_equal) {// 等号if (!secondNum.equals("")) {double calculateResult = calculateFour();refreshOperateResult(String.valueOf(calculateResult));refreshShowText(result);}} else if (id == R.id.btn_sqrt) {// 根号double sqrtResult = Math.sqrt(Double.parseDouble(firstNum));refreshOperateResult(String.valueOf(sqrtResult));refreshShowText(result);} else if (id == R.id.btn_reciprocal) {// 倒数double reciprocalResult = 1.0 / Double.parseDouble(firstNum);refreshOperateResult(String.valueOf(reciprocalResult));refreshShowText(result);} else {// 其它if (result.length() > 0 && operator.equals("")) {clear();}if (operator.equals("")) {firstNum += inputText;} else {secondNum += inputText;}if (showText.equals("0") && !inputText.equals(".")) {refreshShowText(inputText);} else {refreshShowText(showText + inputText);}}}private double calculateFour() {switch (operator) {case "+":return Double.parseDouble(firstNum) + Double.parseDouble(secondNum);case "-":return Double.parseDouble(firstNum) - Double.parseDouble(secondNum);case "×":return Double.parseDouble(firstNum) * Double.parseDouble(secondNum);default:return Double.parseDouble(firstNum) / Double.parseDouble(secondNum);}}private void clear() {refreshOperateResult("");refreshShowText("0");}private void refreshOperateResult(String newResult) {result = newResult;firstNum = result;secondNum = "";operator = "";}private void clearEntryOperate() {String tmp = showText.substring(0, showText.length() - 1);if (tmp.equals("")) {tmp = "0";}refreshShowText(tmp);}// 刷新显示文本private void refreshShowText(String text) {showText = text;integerRemoveDot();tvResult.setText(showText);}private void integerRemoveDot() {int start = showText.indexOf(".");if (start != -1) {int end = showText.length();String value = showText.substring(start + 1, end);if (Double.parseDouble(value) == 0.0) {showText = showText.substring(0, start);}}}
}

4. APK 文件

构建好的 APK 文件见文件开头,可直接下载安装。

5. 项目源码

https://gitee.com/hl0929/calculator

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

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

相关文章

参考RabbitMQ实现一个消息队列

文章目录 前言小小消息管家1.项目介绍2. 需求分析2.1 API2.2 消息应答2.3 网络通信协议设计 3. 开发环境4. 项目结构介绍4.1 配置信息 5. 项目演示 前言 消息队列的本质就是阻塞队列&#xff0c;它的最大用途就是用来实现生产者消费者模型&#xff0c;从而实现解耦合以及削峰填…

Android中简单封装Livedata工具类

Android中简单封装Livedata工具类 前言&#xff1a; 之前讲解过livedata和viewmodel的简单使用&#xff0c;也封装过room工具类&#xff0c;本文是对livedata的简单封装和使用&#xff0c;先是封装了一个简单的工具类&#xff0c;然后实现了一个倒计时工具类的封装. 1.LiveD…

JVM之类加载与字节码(一)

1.类文件结构 一个简单的HelloWorld.Java package cn.itcast.jvm.t5; // HelloWorld 示例 public class HelloWorld { public static void main(String[] args) { System.out.println("hello world"); } }编译为 HelloWorld.class 后的样子如下所示&#xff1a; […

【广州华锐视点】葡萄种植VR虚拟仿真实训平台

随着虚拟现实(VR)技术的不断发展&#xff0c;越来越多的教育领域开始尝试将VR技术应用于教学中。在葡萄栽培这一专业领域&#xff0c;我们开发了一款创新的VR实训课件&#xff0c;旨在为学生提供沉浸式的互动学习体验。本篇文案将为您介绍葡萄种植VR虚拟仿真实训平台所提供的互…

重型并串式液压机械臂建模与simscape仿真

一、建模 Hydraulic manipulator Figure 1 shows different constituting parts of the manipulator considered, with every part labeled using numbers from 1 to 10. For each part, a CAD model is provided. Each file is named in accordance with the corresponding la…

el-popover使用自定义图标

使用el-popover实现鼠标点击或浮动到自定义图标上弹出表格弹窗&#xff0c;官方文档上使用的是按钮el-button&#xff0c;如果想换成图标或其他的组件的话直接把el-button替换掉即可。注意替换之后的组件一定要加slot“reference”&#xff0c;不然组件是显示不出来的。 代码如…

阿里云二级域名配置

阿里云二级域名配置 首先需要进入阿里云控制台的域名管理 1.选择域名点击解析 2.添加记录 3.选择A类型 4.主机记录设置【可以aa.bb或者aa.bb.cc】 到时候会变成&#xff1a;aa.bb.***.com 5.解析请求来源设置为默认 6.记录值 设置为要解析的服务器的ip地址 7.TTL 默认即…

HDFS中的NAMENODE元数据管理(超详细)

元数据管理 元数据是什么元数据管理概述内存元数据元数据文件fsimage内存镜像文件edits log编辑日志 namenode加载元数据文件顺序 元数据管理相关目录文件元数据相关文件VERSIONseen_txid 元数据文件查看&#xff08;OIV,OEV&#xff09;SecondaryNameNode介绍checkpoint机制SN…

24届近5年上海大学自动化考研院校分析

今天给大家带来的是上海大学控制考研分析 满满干货&#xff5e;还不快快点赞收藏 一、上海大学 学校简介 上海大学是上海市属的综合性研究型大学&#xff0c;是教育部与上海市人民政府共建高校&#xff0c;是国家“211 工程”重点建设高校、上海市高水平地方大学建设高校&a…

elementui Cascader 级联选择使用心得

相信大家对于elementui并不陌生&#xff0c;作为适配Vue的优秀UI框架之一&#xff0c;一直被所有的开发者痛并快乐着。今天要记录的就是里边的主角之一Cascader。 首先先介绍一下Cascader ---> 当一个数据集合有清晰的层级结构时&#xff0c;可通过级联选择器逐级查看并选择…

【嵌入式环境下linux内核及驱动学习笔记-(18)LCD驱动框架1-LCD控制原理】

目录 1、LCD显示系统介绍1.1 LCD显示基本原理1.1.1 颜色的显示原理&#xff1a;1.1.2 图像的构成 1.2 LCD接口介绍1.2.1 驱动接口 - MCU接口1.2.2 驱动接口 - RGB接口1.2.3 驱动接口 - LVDS接口1.2.4 驱动接口 - MIPI接口1.2.5 RGB / MIPI / LVDS三种接口方式的区别&#xff1a…

【沁恒蓝牙mesh】CH58x系统时钟配置与计算

本文主要记录了【沁恒蓝牙mesh】CH58x系统时钟配置与计算 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是喜欢记录零碎知识点的小菜鸟。&#x1f60e;&#x1f4dd; 个人主页&#xff1a;欢迎访问我的 Ethernet_Comm 博客主页&#x1f525;&#x1f389; 支持我&am…

Containerd数据持久化和网络管理

1. 轻量级容器管理工具 Containerd 2. Containerd的两种安装方式 3. Containerd容器镜像管理 4. Containerd数据持久化和网络管理 1、Containerd NameSpace管理 containerd中namespace的作用为:隔离运行的容器&#xff0c;可以实现运行多个容器。 查看命令帮助 # ctr namespac…

[IDEA]使用idea比较两个jar包的差异

除了一些小工具外&#xff0c;idea自带了jar包比较的功能。 把需要比对的jar包放到任意目录下&#xff0c;然后选中两个需要比较的jar包&#xff0c;右键&#xff0c;选择Compare Archives&#xff0c;然后就可以比较了。 这次疏忽了&#xff0c;每次打包前需要commit界面看一下…

极光笔记 | 浅谈企业级SaaS产品的客户成长旅程管理(上)—— 分析篇

本文作者&#xff1a;陈伟&#xff08;极光用户体验部高级总监&#xff09; “企业级SaaS产品与C端互联网产品特征差异很大&#xff0c;有些甚至是截然相反&#xff0c;这些特征也会成为后续客户成长旅程的重要影响变量。本文就如何设计并服务好企业级SaaS产品客户成长旅程进行…

CS 144 Lab Five -- the network interface

CS 144 Lab Five -- the network interface TCP报文的数据传输方式地址解析协议 ARPARP攻击科普 Network Interface 具体实现测试tcp_ip_ethernet.ccTCPOverIPv4OverEthernetAdapterTCPOverIPv4OverEthernetSpongeSocket通信过程 对应课程视频: 【计算机网络】 斯坦福大学CS144…

「Qt」常用事件介绍

&#x1f514; 在开始本文的学习之前&#xff0c;笔者希望读者已经阅读过《「Qt」事件概念》这篇文章了。本文会在上篇文章的基础上&#xff0c;进一步介绍 Qt 中一些比较常用的事件。 0、引言 当我们想要让控件收到某个事件时做一些操作&#xff0c;通常都需要重写相应的事件处…

js-5:==和===的区别,分别在什么情况下使用

1、等于操作符 等于操作符用两个等号&#xff08;&#xff09;表示&#xff0c;如果操作数相等&#xff0c;则返回true。 javascript中存在隐式转换&#xff0c;等于操作符在比较中会先进行类型转换&#xff0c;再确定操作数是否相等。 遵循以下规则&#xff1a; 如果任一操作数…

Jupyter Notebook 未授权访问远程命令执行漏洞

漏洞描述 Jupyter是一个开源的交互式计算环境&#xff0c;它支持多种编程语言&#xff0c;包括Python、R、Julia等。Jupyter的名称来源于三种编程语言的缩写&#xff1a;Ju(lia)、Py(thon)和R。 Jupyter的主要特点是它以笔记本&#xff08;Notebook&#xff09;的形式组织代码…

PoseFormer:基于视频的2D-to-3D单人姿态估计

3D Human Pose Estimation with Spatial and Temporal Transformers论文解析 摘要1. 简介2. Related Works2.1 2D-to-3D Lifting HPE2.2 GNNs in 3D HPE2.3 Vision Transformers 3. Method3.1 Temporal Transformer Baseline3.2 PoseFormer: Spatial-Temporal TransformerSpati…