Android开发应用案例——简易计算器(附完整源码)
短信预约 -IT技能 免费直播动态提醒
使用android studio开发简易计算器app(完整源码可在博主资源中自行下载)
最终效果:
开发步骤:
创建一个名为calculator的新项目
编写代码
项目目录
MyTextView文件
package com.example.calculator.my_control;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.util.AttributeSet;import androidx.annotation.NonNull;import androidx.annotation.Nullable;public class MyTextView extends androidx.appcompat.widget.AppCompatTextView { Paint paint = new Paint();//创建一个paint对象 public MyTextView(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs);//构造函数 } @Override//重写方法 protected void onDraw(Canvas canvas){ super.onDraw(canvas); paint.setColor(Color.BLACK);//设置paint的颜色 //绘制边框 canvas.drawLine(0,0,this.getWidth(),0,paint);//绘制上方的边框 canvas.drawLine(0,this.getHeight()-1,this.getWidth(),this.getHeight()-1,paint);//绘制下方的边框(因为会被遮挡,所以需要-1) canvas.drawLine(0,0,0,this.getHeight(),paint);//绘制左边的边框 canvas.drawLine(this.getWidth()-1,0,this.getWidth()-1,this.getHeight(),paint);//绘制右边的边框(因为会被遮挡,所以需要-1) }}
MainActivity文件
package com.example.calculator;import androidx.appcompat.app.AppCompatActivity;import androidx.databinding.DataBindingUtil;import androidx.lifecycle.Observer;import androidx.lifecycle.ViewModelProvider;import android.database.DatabaseUtils;import android.os.Bundle;import android.view.View;import com.example.calculator.databinding.ActivityMainBinding;public class MainActivity extends AppCompatActivity { private ActivityMainBinding binding;//组件存储类 private MyViewModel myViewModel;//数据模型 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this,R.layout.activity_main);//获取所有控件 myViewModel = new ViewModelProvider(this,new ViewModelProvider.NewInstanceFactory()).get(MyViewModel.class);//获取数据模型 //事件监听 myViewModel.getMainNum().observe(this, new Observer() { @Override public void onChanged(String s) {//监听 mainNum数据发生改变的监听 binding.myTextView.setText(myViewModel.getMainNum().getValue());//让 myTextView显示mainNum的数值,也就是计算器中的输入框显示数值 if (myViewModel.sign2.equals("")){ if (myViewModel.sign1.equals("")){ binding.textView2.setText(myViewModel.getMainNum().getValue());//让 textView显示式子,也就是输入框上面的小框显示计算式 } else {//如果是像a + b这种形式的式子时 binding.textView2.setText(myViewModel.num[0] + myViewModel.sign1 + myViewModel.getMainNum().getValue()); } } else {//如果是像a+b*c这种形式的式子的时候 binding.textView2.setText(myViewModel.num[0] + myViewModel.sign1 + myViewModel.num[1] + myViewModel.sign2 + myViewModel.getMainNum().getValue()); } } }); binding.button0.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { myViewModel.setMainNum("0"); } }); binding.button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { myViewModel.setMainNum("1"); } }); binding.button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { myViewModel.setMainNum("2"); } }); binding.button3.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { myViewModel.setMainNum("3"); } }); binding.button4.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { myViewModel.setMainNum("4"); } }); binding.button5.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { myViewModel.setMainNum("5"); } }); binding.button6.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { myViewModel.setMainNum("6"); } }); binding.button7.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { myViewModel.setMainNum("7"); } }); binding.button8.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { myViewModel.setMainNum("8"); } }); binding.button9.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { myViewModel.setMainNum("9"); } }); //给小数点按钮的监听 binding.button15.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (!myViewModel.havePoint){ myViewModel.getMainNum().setValue(myViewModel.getMainNum().getValue()+"."); myViewModel.havePoint=true; } } }); //给加号按钮的监听 binding.button11.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (myViewModel.sign1.equals("")){ myViewModel.sign1="+"; myViewModel.num[0] = myViewModel.getMainNum().getValue(); myViewModel.getMainNum().setValue("0"); myViewModel.havePoint=false; } else if (myViewModel.sign2.equals("")){//如果是像a+b这种形式的式子时 myViewModel.num[0] = myViewModel.mainNumWithNum_0_Tocal(); myViewModel.sign1="+"; myViewModel.getMainNum().setValue("0"); myViewModel.havePoint = false; } else {//如果是像a+b*c这种形式的式子时 myViewModel.getMainNum().setValue(myViewModel.mainNumWith_Num_1_Tocal()); myViewModel.sign2=""; myViewModel.num[1] = ""; myViewModel.num[0] = myViewModel.mainNumWithNum_0_Tocal(); myViewModel.sign1 = "+"; myViewModel.getMainNum().setValue("0"); myViewModel.havePoint = false; } } }); //给减号设置监听 binding.button12.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (myViewModel.sign1.equals("")){ myViewModel.sign1="-"; myViewModel.num[0] = myViewModel.getMainNum().getValue(); myViewModel.getMainNum().setValue("0"); myViewModel.havePoint=false; } else if (myViewModel.sign2.equals("")){//如果是像a-b这种形式的式子时 myViewModel.num[0] = myViewModel.mainNumWithNum_0_Tocal(); myViewModel.sign1="-"; myViewModel.getMainNum().setValue("0"); myViewModel.havePoint = false; } else {//如果是像a-b*c这种形式的式子时 myViewModel.getMainNum().setValue(myViewModel.mainNumWith_Num_1_Tocal()); myViewModel.sign2=""; myViewModel.num[1] = ""; myViewModel.num[0] = myViewModel.mainNumWithNum_0_Tocal(); myViewModel.sign1 = "-"; myViewModel.getMainNum().setValue("0"); myViewModel.havePoint = false; } } }); //给乘号设置监听 binding.button13.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (myViewModel.sign1.equals("")){ myViewModel.sign1 = "*"; myViewModel.num[0] = myViewModel.getMainNum().getValue(); myViewModel.getMainNum().setValue("0"); myViewModel.havePoint = false; } else if (myViewModel.sign2.equals("")){ if (myViewModel.sign1.equals("*") || myViewModel.sign1.equals("/")){//按顺序进行计算 myViewModel.num[0] = myViewModel.mainNumWithNum_0_Tocal(); myViewModel.sign1="*"; myViewModel.getMainNum().setValue("0"); myViewModel.havePoint = false; } else {//如果sign1是减号或者加号时 myViewModel.num[1] = myViewModel.getMainNum().getValue(); myViewModel.sign2 = "*"; myViewModel.getMainNum().setValue("0"); myViewModel.havePoint = false; } } else {//如果像a+b*c形式的式子时 myViewModel.num[1] = myViewModel.mainNumWith_Num_1_Tocal(); myViewModel.sign2 = "*"; myViewModel.getMainNum().setValue("0"); myViewModel.havePoint = false; } } }); //给除号设置监听 binding.button14.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (myViewModel.sign1.equals("")){ myViewModel.sign1 = "/"; myViewModel.num[0] = myViewModel.getMainNum().getValue(); myViewModel.getMainNum().setValue("0"); myViewModel.havePoint = false; } else if (myViewModel.sign2.equals("")){ if (myViewModel.sign1.equals("*") || myViewModel.sign1.equals("/")){//按顺序进行计算 myViewModel.num[0] = myViewModel.mainNumWithNum_0_Tocal(); myViewModel.sign1="/"; myViewModel.getMainNum().setValue("0"); myViewModel.havePoint = false; } else {//如果sign1是减号或者加号时 myViewModel.num[1] = myViewModel.getMainNum().getValue(); myViewModel.sign2 = "/"; myViewModel.getMainNum().setValue("0"); myViewModel.havePoint = false; } } else {//如果像a+b/c形式的式子时 myViewModel.num[1] = myViewModel.mainNumWith_Num_1_Tocal(); myViewModel.sign2 = "/"; myViewModel.getMainNum().setValue("0"); myViewModel.havePoint = false; } } }); //给 清空 设置监听 binding.button17.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { myViewModel.sign2 = ""; myViewModel.num[1] = ""; myViewModel.sign1 = ""; myViewModel.num[0] = ""; myViewModel.getMainNum().setValue("0"); myViewModel.havePoint = false; } }); //给 计算按钮 设置监听 binding.button16.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (myViewModel.sign2.equals("")){ if (!myViewModel.sign1.equals("")){ myViewModel.getMainNum().setValue(myViewModel.mainNumWithNum_0_Tocal()); if (myViewModel.getMainNum().getValue().contains(".")){//判断是否包含小数点myViewModel.havePoint = true; } else myViewModel.havePoint = false; myViewModel.num[0]=""; myViewModel.sign1 = ""; } } else {//如果是像 a+b*c 这种形式的式子时 myViewModel.getMainNum().setValue(myViewModel.mainNumWith_Num_1_Tocal()); myViewModel.num[1] = ""; myViewModel.sign2 = ""; myViewModel.getMainNum().setValue(myViewModel.mainNumWithNum_0_Tocal()); if (myViewModel.getMainNum().getValue().contains(".")){//判断是否包含小数点 myViewModel.havePoint = true; } else myViewModel.havePoint = false; myViewModel.num[0]=""; myViewModel.sign1 = ""; } binding.textView2.setText(myViewModel.num[0] + myViewModel.sign1 + myViewModel.getMainNum().getValue()); } }); //给 退格按钮 设置监听 binding.imageButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (!myViewModel.getMainNum().getValue().equals("0")){ myViewModel.getMainNum().setValue(myViewModel.getMainNum().getValue().substring(0,myViewModel.getMainNum().getValue().length()-1));//不为空,长度减1 if (myViewModel.getMainNum().getValue().equals("")){ myViewModel.getMainNum().setValue("0");//如果为空,将其设为0 } } } }); }}
MyViewModel
package com.example.calculator;import androidx.lifecycle.MutableLiveData;import androidx.lifecycle.ViewModel;//用来存储一些数据模型public class MyViewModel extends ViewModel { private MutableLiveData mainNum;//主数值(用户正在操作的数) public boolean havePoint =false;//用于记录主数值中是否包含小数点 public String sign1 = "",sign2 = "";//用于存储运算符号 public String num[]={"",""};//用于存储参与计算的数值 public MutableLiveData getMainNum(){ if (mainNum == null){ mainNum = new MutableLiveData<>(); mainNum.setValue("0"); } return mainNum; } public void setMainNum(String n ){ if (mainNum.getValue().equals("0")){ mainNum.setValue(n); } else { mainNum.setValue(mainNum.getValue() + n); } } public String mainNumWithNum_0_Tocal(){ String value = "0"; if (mainNum.getValue().contains(".") || num[0].contains(".")) {//如果两个数的其中一个有小数点的运算 switch (sign1){ case "+": value = String.valueOf(Double.valueOf(num[0]) + Double.valueOf(mainNum.getValue())); break; case "-": value = String.valueOf(Double.valueOf(num[0]) - Double.valueOf(mainNum.getValue())); break; case "*": value = String.valueOf(Double.valueOf(num[0]) * Double.valueOf(mainNum.getValue())); break; case "/": if (mainNum.getValue().equals("0")){ mainNum.setValue("1"); } value = String.valueOf(Double.valueOf(num[0]) / Double.valueOf(mainNum.getValue())); } } else { switch (sign1){//如果没有小数点则为整数运算 case "+": value = String.valueOf(Integer.valueOf(num[0]) + Integer.valueOf(mainNum.getValue())); break; case "-": value = String.valueOf(Integer.valueOf(num[0]) - Integer.valueOf(mainNum.getValue())); break; case "*": value = String.valueOf(Integer.valueOf(num[0]) * Integer.valueOf(mainNum.getValue())); break; case "/"://除号依旧为小数运算方式 if (mainNum.getValue().equals("0")){ mainNum.setValue("1"); } value = String.valueOf(Double.valueOf(num[0]) / Double.valueOf(mainNum.getValue())); } } return value; } public String mainNumWith_Num_1_Tocal(){ String value = "0"; if (mainNum.getValue().contains(".") || num[0].contains(".")) {//如果两个数的其中一个有小数点的运算 switch (sign2){ case "*": value = String.valueOf(Double.valueOf(num[1]) * Double.valueOf(mainNum.getValue())); break; case "/": if (mainNum.getValue().equals("0")){ mainNum.setValue("1"); } value = String.valueOf(Double.valueOf(num[1]) / Double.valueOf(mainNum.getValue())); } } else { switch (sign2){//如果没有小数点则为整数运算 case "*": value = String.valueOf(Integer.valueOf(num[1]) * Integer.valueOf(mainNum.getValue())); break; case "/"://除号依旧为小数运算方式 if (mainNum.getValue().equals("0")){ mainNum.setValue("1"); } value = String.valueOf(Double.valueOf(num[1]) / Double.valueOf(mainNum.getValue())); } } return value; }}
activity_main.xml
补充:
1、在drawable中引入backspace矢量图
2、在build.gradle文件中添加dataBinding{enabled true}代码
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341