Android 开发笔记___初级控件之实战__计算器

功能简单,实现并不难,对于初学者可以总和了解初级控件的基本使用。
用到的知识点如下:
- 线性布局 LinearLayout:整体界面是从上往下的,因此需要垂直方向的linearlayout;下面每行四个按钮,需要水平的linearlayout。
- 滚动视图 ScrollView :虽然界面不宽也不高,以防万一,有可能会遇到屏幕特别小的手机,因此用一个垂直方向的scrollview。
- 文本视图 TextView :上面标题就是一个textview,结果显示也是textview,但是更高级。能够从下往上滚动,前面的聊天室效果里用到过。
- 按钮 Button :下面的数字、运算符都是按钮。
- 图像视图 ImageView :未用到。
- 图像按钮 ImageButton :由于开根号运算符(√)虽然可以打出来,但是有点不一样,因此需要用到一个图像,就用到了图像按钮。
- 状态列表图形 :都有按下和弹起两种状态,因此订制了按钮的自定义样式。
- 形状图形 :运算结果用到的textview是一个圆角的矩形,所以定义了shape文件,把它作为文本视图的背景。
- 九宫格图片 :最下面的“0”按钮是有点大,因此需要两倍那么大的图片,如果使用普通的图片则会拉宽,效果很不好。因此就用到了。
style
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="btn_cal">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">match_parent</item>
<item name="android:layout_weight">1</item>
<item name="android:gravity">center</item>
<item name="android:textColor">@color/black</item>
<item name="android:textSize">30sp</item>
<item name="android:background">@drawable/btn_nine_selector</item>
</style>
</resources>
xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp"
android:gravity="top|center"
android:orientation="vertical"> <ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="简单计算器"
android:textColor="#000000"
android:textSize="22sp" /> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shape_white_with_stroke"
android:orientation="vertical"> <TextView
android:id="@+id/tv_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right|bottom"
android:lines="3"
android:maxLines="3"
android:scrollbars="vertical"
android:textColor="#000000"
android:textSize="25sp" />
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"> <LinearLayout
android:layout_width="match_parent"
android:layout_height="75dp"
android:orientation="horizontal"> <Button
android:id="@+id/btn_cancel"
style="@style/btn_cal"
android:text="CE" /> <Button
android:id="@+id/btn_divide"
style="@style/btn_cal"
android:text="÷" /> <Button
android:id="@+id/btn_multiply"
style="@style/btn_cal"
android:text="×" /> <Button
android:id="@+id/btn_clear"
style="@style/btn_cal"
android:text="C" />
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="75dp"
android:orientation="horizontal"> <Button
android:id="@+id/btn_seven"
style="@style/btn_cal"
android:text="7" /> <Button
android:id="@+id/btn_eight"
style="@style/btn_cal"
android:text="8" /> <Button
android:id="@+id/btn_nine"
style="@style/btn_cal"
android:text="9" /> <Button
android:id="@+id/btn_plus"
style="@style/btn_cal"
android:text="+" />
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="75dp"
android:orientation="horizontal"> <Button
android:id="@+id/btn_four"
style="@style/btn_cal"
android:text="4" /> <Button
android:id="@+id/btn_five"
style="@style/btn_cal"
android:text="5" /> <Button
android:id="@+id/btn_six"
style="@style/btn_cal"
android:text="6" /> <Button
android:id="@+id/btn_minus"
style="@style/btn_cal"
android:text="-" />
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="75dp"
android:orientation="horizontal"> <Button
android:id="@+id/btn_one"
style="@style/btn_cal"
android:text="1" /> <Button
android:id="@+id/btn_two"
style="@style/btn_cal"
android:text="2" /> <Button
android:id="@+id/btn_three"
style="@style/btn_cal"
android:text="3" /> <ImageButton
android:id="@+id/ib_sqrt"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:scaleType="centerInside"
android:src="@drawable/sqrt"
android:background="@drawable/btn_nine_selector"/>
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="75dp"
android:orientation="horizontal"> <Button
android:id="@+id/btn_zero"
style="@style/btn_cal"
android:layout_weight="2"
android:text="0" /> <Button
android:id="@+id/btn_dot"
style="@style/btn_cal"
android:text="." /> <Button
android:id="@+id/btn_equal"
style="@style/btn_cal"
android:text="=" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView> </LinearLayout>
nineselec0tor
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/button_pressed" />
<item android:drawable="@drawable/button_normal" />
</selector>
putong
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/button_pressed_orig" />
<item android:drawable="@drawable/button_normal_orig" />
</selector>0
shape_oval
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" > <solid android:color="#ff66aa" /> <stroke
android:width="1dp"
android:color="#ffaaaaaa" /> </shape>
rect
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" > <solid android:color="#ffdd66" /> <stroke
android:width="1dp"
android:color="#ffaaaaaa" /> <corners
android:bottomLeftRadius="10dp"
android:bottomRightRadius="10dp"
android:topLeftRadius="10dp"
android:topRightRadius="10dp" /> </shape>
white_stroke
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" > <solid android:color="#ffffff" /> <stroke
android:width="1dp"
android:color="#bbbbbb" /> <corners
android:bottomLeftRadius="10dp"
android:bottomRightRadius="10dp"
android:topLeftRadius="10dp"
android:topRightRadius="10dp" /> </shape>
main
package com.example.alimjan.hello_world; import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable; /**
* Created by alimjan on 7/1/2017.
*/ import android.support.v7.app.AppCompatActivity;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast; import com.example.alimjan.hello_world.Arith; public class class__2_5 extends AppCompatActivity implements View.OnClickListener { private final static String TAG = "CalculatorActivity";
private TextView tv_result; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.code_2_5);
tv_result = (TextView) findViewById(R.id.tv_result);
tv_result.setMovementMethod(new ScrollingMovementMethod()); findViewById(R.id.btn_cancel).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_zero).setOnClickListener(this);
findViewById(R.id.btn_dot).setOnClickListener(this);
findViewById(R.id.btn_equal).setOnClickListener(this);
findViewById(R.id.ib_sqrt).setOnClickListener(this);
} @Override
public void onClick(View v) {
int resid = v.getId();
String inputText;
if (resid == R.id.ib_sqrt) {
inputText = "√";
} else {
inputText = ((TextView) v).getText().toString();
}
Log.d(TAG, "resid="+resid+",inputText="+inputText);
if (resid == R.id.btn_clear) {
clear("");
} else if (resid == R.id.btn_cancel) {
if (operator.equals("") == true) {
if (firstNum.length() == 1) {
firstNum = "0";
} else if (firstNum.length() > 0) {
firstNum = firstNum.substring(0, firstNum.length() - 1);
} else {
Toast.makeText(this, "没有可取消的数字了", Toast.LENGTH_SHORT).show();
return;
}
showText = firstNum;
tv_result.setText(showText);
} else {
if (nextNum.length() == 1) {
nextNum = "";
} else if (nextNum.length() > 0) {
nextNum = nextNum.substring(0, nextNum.length() - 1);
} else {
Toast.makeText(this, "没有可取消的数字了", Toast.LENGTH_SHORT).show();
return;
}
showText = showText.substring(0, showText.length() - 1);
tv_result.setText(showText);
}
} else if (resid == R.id.btn_equal) {
if (operator.length() == 0 || operator.equals("=") == true) {
Toast.makeText(this, "请输入运算符", Toast.LENGTH_SHORT).show();
return;
} else if (nextNum.length() <= 0) {
Toast.makeText(this, "请输入数字", Toast.LENGTH_SHORT).show();
return;
}
if (caculate() == true) {
operator = inputText;
showText = showText + "=" + result;
tv_result.setText(showText);
} else {
return;
}
} else if (resid == R.id.btn_plus || resid == R.id.btn_minus
|| resid == R.id.btn_multiply || resid == R.id.btn_divide ) {
if (firstNum.length() <= 0) {
Toast.makeText(this, "请输入数字", Toast.LENGTH_SHORT).show();
return;
}
if (operator.length() == 0 || operator.equals("=") == true
|| operator.equals("√") == true) {
operator = inputText;// 操作符
showText = showText + operator;
tv_result.setText(showText);
} else {
Toast.makeText(this, "请输入数字", Toast.LENGTH_SHORT).show();
return;
}
} else if (resid == R.id.ib_sqrt) {
if (firstNum.length() <= 0) {
Toast.makeText(this, "请输入数字", Toast.LENGTH_SHORT).show();
return;
}
if (Double.parseDouble(firstNum) < 0) {
Toast.makeText(this, "开根号的数值不能小于0", Toast.LENGTH_SHORT).show();
return;
}
result = String.valueOf(Math.sqrt(Double.parseDouble(firstNum)));
firstNum = result;
nextNum = "";
operator = inputText;
showText = showText + "√=" + result;
tv_result.setText(showText);
Log.d(TAG, "result="+result+",firstNum="+firstNum+",operator="+operator);
} else {
if (operator.equals("=") == true) {
operator = "";
firstNum = "";
showText = "";
}
if (resid == R.id.btn_dot) {
inputText = ".";
}
if (operator.equals("") == true) {
firstNum = firstNum + inputText;
} else {
nextNum = nextNum + inputText;
}
showText = showText + inputText;
tv_result.setText(showText);
}
return;
} private String operator = ""; // 操作符
private String firstNum = ""; // 前一个操作数
private String nextNum = ""; // 后一个操作数
private String result = ""; // 当前的计算结果
private String showText = ""; // 显示的文本内容 // 开始加减乘除四则运算
private boolean caculate() {
if (operator.equals("+") == true) {
result = String.valueOf(Arith.add(firstNum, nextNum));
} else if (operator.equals("-") == true) {
result = String.valueOf(Arith.sub(firstNum, nextNum));
} else if (operator.equals("×") == true) {
result = String.valueOf(Arith.mul(firstNum, nextNum));
} else if (operator.equals("÷") == true) {
if ("0".equals(nextNum)) {
Toast.makeText(this, "被除数不能为零", Toast.LENGTH_SHORT).show();
return false;
} else {
result = String.valueOf(Arith.div(firstNum, nextNum));
}
}
firstNum = result;
nextNum = "";
return true;
} // 清空并初始化
private void clear(String text) {
showText = text;
tv_result.setText(showText);
operator = "";
firstNum = "";
nextNum = "";
result = "";
} public static void startHome(Context mContext) {
Intent intent = new Intent(mContext, class__2_5.class);
mContext.startActivity(intent);
} }
Arith
package com.example.alimjan.hello_world;
import java.math.BigDecimal;
public class Arith {
// 默认除法运算精度
private static final int DEF_DIV_SCALE = 10;
// 这个类不能实例化
private Arith() {
;
}
/**
* 提供精确的加法运算。
*
* @param v1
* 被加数
* @param v2
* 加数
* @return 两个参数的和
*/
public static String add(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return String.valueOf(b1.add(b2));
}
/**
* 提供精确的加法运算。
*
* @param v1
* 被加数
* @param v2
* 加数
* @return 两个参数的和
*/
public static String add(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return String.valueOf(b1.add(b2));
}
/**
* 提供精确的减法运算。
*
* @param v1
* 被减数
* @param v2
* 减数
* @return 两个参数的差
*/
public static String sub(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return String.valueOf(b1.subtract(b2));
}
/**
* 提供精确的减法运算。
*
* @param v1
* 被减数
* @param v2
* 减数
* @return 两个参数的差
*/
public static String sub(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return String.valueOf(b1.subtract(b2));
}
/**
* 提供精确的乘法运算。
*
* @param v1
* 被乘数
* @param v2
* 乘数
* @return 两个参数的积
*/
public static String mul(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return String.valueOf(b1.multiply(b2));
}
/**
* 提供精确的乘法运算。
*
* @param v1
* 被乘数
* @param v2
* 乘数
* @return 两个参数的积
*/
public static String mul(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return String.valueOf(b1.multiply(b2));
}
/**
* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。
*
* @param v1
* 被除数
* @param v2
* 除数
* @return 两个参数的商
*/
public static String div(double v1, double v2) {
return div(v1, v2, DEF_DIV_SCALE);
}
/**
* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。
*
* @param v1
* 被除数
* @param v2
* 除数
* @return 两个参数的商
*/
public static String div(String v1, String v2) {
return div(v1, v2, DEF_DIV_SCALE);
}
/**
* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。
*
* @param v1
* 被除数
* @param v2
* 除数
* @param scale
* 表示表示需要精确到小数点以后几位。
* @return 两个参数的商
*/
public static String div(double v1, double v2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return String.valueOf(b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP));
}
/**
* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。
*
* @param v1
* 被除数
* @param v2
* 除数
* @param scale
* 表示表示需要精确到小数点以后几位。
* @return 两个参数的商
*/
public static String div(String v1, String v2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
BigDecimal result = null;
try {
result = b1.divide(b2);
} catch (Exception e) {
result = b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP);
}
return String.valueOf(result);
}
/**
* 提供精确的小数位四舍五入处理。
*
* @param v
* 需要四舍五入的数字
* @param scale
* 小数点后保留几位
* @return 四舍五入后的结果
*/
public static String round(double v, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
BigDecimal one = new BigDecimal("1");
return String.valueOf(b.divide(one, scale, BigDecimal.ROUND_HALF_UP));
}
/**
* 提供精确的小数位四舍五入处理。
*
* @param v
* 需要四舍五入的数字
* @param scale
* 小数点后保留几位
* @return 四舍五入后的结果
*/
public static String round(String v, int String, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(v);
BigDecimal one = new BigDecimal("1");
b.divide(one, scale, BigDecimal.ROUND_HALF_UP);
return null;
}
}
Android 开发笔记___初级控件之实战__计算器的更多相关文章
- Android 开发笔记___基本适配器的使用__BaseAdapter
之前用到过ArryAdapter适用于纯文本的列表数据,SimpleAdapter适用于带图标的列表数据,但在实际应用中常常有更复杂的列表,比如同一项中存在多个控件,这时候用前面的两个会比较复杂,而且 ...
- Android 开发笔记___实战项目:购物车
购物车的应用很广泛,电商app基本上都有它的身影.由于它用到了多种存储方式,通过项目对数据的存储有更高层次的了解. 1.设计思路 首先看看购物车的外观.第一次进入时里面是空的,去购物页面加入购物车以后 ...
- Android 开发笔记___时间选择器---timePicker
像datepicker一样,也有timepicker. 同样有timepickerdialog 所用到的方法还是一样,监听时间选择器的变化. package com.example.alimjan.h ...
- Android 开发笔记___存储方式__共享参数__sharedprefences
Android 的数据存储方式有四种,这次是[共享参数__sharedprefences] 听起来挺别扭的,平时看到的app里面,当用户删除了一些软件以后下次安装,发现原来的设置还在,这种情况就是把一 ...
- Android 开发笔记___登陆app
package com.example.alimjan.hello_world; /** * Created by alimjan on 7/4/2017. */ import android.con ...
- Android 开发笔记___复选框__checkbox
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout ...
- Android 开发笔记___图像按钮__imageButton
IMAGEBUTTON 其实派生自image view,而不是派生自button.,image view拥有的属性和方法,image button 统统拥有,只是imagebutton有个默认的按钮外 ...
- Android 开发笔记___滚动视图__scroll view
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...
- Android 开发笔记___图像视图__简单截屏
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...
随机推荐
- SpringBoot开发案例之mail中文附件乱码
前一段时间做过一个邮件发送的服务,以前大体都测试过,文本.图片.附件都是没有问题的,可有同事反应发送的附件名称有中文乱码,类似如下截图展示: 咋一看不像乱码,抱着试试看的态度,为MimeMessage ...
- linux kill 命令
kill 命令的用途 kill 命令很容易让人产生误解,以为它仅仅就是用来杀死进程的.我们来看一下 man page 对它的解释:kill - send a signal to a process. ...
- Hive任务优化(1)
一个Hive查询生成多个Map Reduce Job,一个Map Reduce Job又有Map,Reduce,Spill,Shuffle,Sort等多个阶段,所以针对Hive查询的优化可以大致分为针 ...
- Mysql配置文件my.cnf详细说明
[表名大小写配置] MySQL在Linux下数据库名.表名.列名.别名大小写规则: 1.数据库名与表名是严格区分大小写 2.表的别名是严格区分大小写 3.列名与列的别名在所有的情况下均是忽略大小 ...
- 苹果iPhone X上搭载的那颗A11仿生芯片,到底牛在哪?
苹果iPhone X上搭载的那颗A11仿生芯片,到底牛在哪? 上周,苹果公司在刚刚落成投入使用的“飞船”新总部(Apple Park)举行2017年秋季新品发布会,整场发布会基本被iPhone X抢尽 ...
- lambda表达式杂谈
var personInfo = [ { name: "张三", age: 20, gender: "male" }, { name: "李四&quo ...
- Intellij idea史上最简单的教程之Linux下安装与破解Intellij idea2017
一.前言 这一节我们介绍在Linux下如何安装与破解Intellij idea2017.现在有很多公司开发环境都是Linux,所以掌握在Linux环境下使用Idea办公也是咱们必须得掌握的技能. 记住 ...
- 童话故事 --- 通信协议之 HDLC 浅析
高飞狗: "高飞的白鹭浮水的鹅,唐诗里有画-" 布鲁托: "高飞狗,又在做你的高飞梦哪!" 高飞狗: "哈罗,布鲁托,这几天好郁闷呐!" 布 ...
- SQL Server 锁机制 悲观锁 乐观锁 实测解析
先引入一些概念,直接Copy其他Blogs中的,我就不单独写了. 一.为什么会有锁 多个用户同时对数据库的并发操作时会带来以下数据不一致的问题: 1.丢失更新 A,B两个用户读同一数据并进行修改,其中 ...
- 【京东个人中心】——Nodejs/Ajax/HTML5/Mysql爬坑之注册与登录监听
一.引言 在数据库和静态页面都创建好之后,下面就该接着完成后台Node.js监听注册和登录的部分了.这个部分主要使用的技术是:Node.js的Express框架和ajax异步请求.登录和注册的代码实现 ...