制作一个简易的计算器app

这篇具有很好参考价值的文章主要介绍了制作一个简易的计算器app。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

github项目地址:https://github.com/13008451162/AndroidMoblieCalculator

1、Ui开发

笔者的Ui制作的制作的比较麻烦仅供参考,在这里使用了多个LinearLayout对屏幕进行了划分。不建议大家这样做最好使用GridLayout会更加快捷简单

笔者大致划分是这样的:

制作一个简易的计算器app,Android,android,开发语言,java,xml

使用了四个大框,在第四个大框里面有多个小框

制作一个简易的计算器app,Android,android,开发语言,java,xml
最终界面如下:
制作一个简易的计算器app,Android,android,开发语言,java,xml

然后在每一个小框写计算机的按键。

代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/TwoArrows_Shrink"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_marginTop="15dp"
            android:layout_marginLeft="10dp"
            android:src="@drawable/two_arrows_shrink"/>

        <ImageView
            android:id="@+id/FourSquares"
            android:layout_width="30dp"
            android:layout_height="30dp"
           android:layout_marginLeft="220dp"
            android:layout_marginTop="15dp"
            android:src="@drawable/four_squares"/>

        <ImageView
            android:id="@+id/ThreePoints"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_marginLeft="15dp"
            android:clickable="true"
            android:layout_marginTop="15dp"
            android:src="@drawable/three_points"/>
    </LinearLayout>

    <EditText
        android:id="@+id/Scanf_EditText"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="3"
        android:background="@null"
        android:gravity="bottom|right"
        android:text=""
        android:lines="1"
        android:inputType="textVisiblePassword"
        android:textSize="40dp"
        android:paddingRight="16dp"
        android:textColor="@android:color/black"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/Printf_text"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center|right"
        android:text=""
        android:textSize="25dp"
        android:layout_margin="8dp"
        android:paddingRight="13dp"
        android:textColor="@android:color/black"
        android:textStyle="bold" />

    <LinearLayout
        android:id="@+id/keyboard"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="5"
        android:orientation="vertical"
        android:layout_margin="10dp">

        <!--  C % <- /      -->
        <LinearLayout
            android:id="@+id/One"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            >

            <!--            C-->
            <FrameLayout
                android:id="@+id/leftCFrmae"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
              >

                <ImageButton
                    android:id="@+id/leftC"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_grey_round"
                    android:layout_marginStart="20dp"
                    />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="("
                    android:textSize="25sp"
                    android:textColor="@android:color/black"
                    android:layout_gravity="center"
                    android:layout_marginLeft="10dp"
                    android:padding="8dp"
                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4"/>
            </FrameLayout>

            <FrameLayout
                android:id="@+id/RightCFrame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="20dp">

                <ImageButton
                    android:id="@+id/RightC"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_grey_round"/>

                <TextView
                    android:layout_width="19dp"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:paddingLeft="10dp"

                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4"
                    android:text=")"
                    android:textColor="@android:color/black"
                    android:textSize="25sp" />
            </FrameLayout>

            <FrameLayout
                android:id="@+id/DeleteOneFrame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageButton
                    android:id="@+id/DeleteOne"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_grey_round"
                    android:layout_marginStart="20dp"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="11dp"
                    android:padding="8dp"
                    android:text="DEL"
                    android:textColor="@android:color/black"
                    android:textSize="25sp"
                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4"/>
            </FrameLayout>

            <FrameLayout
                android:id="@+id/DivisionFrame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageButton
                    android:id="@+id/Division"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_grey_round"
                    android:layout_marginStart="20dp"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="11dp"
                    android:padding="8dp"
                    android:text=""
                    android:textColor="@android:color/black"
                    android:textSize="25sp"
                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4"/>
            </FrameLayout>

        </LinearLayout>

        <!-- 7 8 9 x       -->
        <LinearLayout
            android:id="@+id/Two"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:paddingTop="15dp"
            >

            <FrameLayout
                android:id="@+id/SevenNumFrame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageButton
                    android:id="@+id/SevenNum"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_white_round"
                    android:layout_marginStart="20dp"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="11dp"
                    android:padding="8dp"
                    android:text="7"
                    android:textColor="@android:color/black"
                    android:textSize="28dp"
                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4" />

            </FrameLayout>

            <FrameLayout
                android:id="@+id/EightNumFrame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageButton
                    android:id="@+id/EightNum"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_white_round"
                    android:layout_marginStart="20dp"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="11dp"
                    android:padding="8dp"
                    android:text="8"
                    android:textColor="@android:color/black"
                    android:textSize="28dp"
                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4" />

            </FrameLayout>

            <FrameLayout
                android:id="@+id/NineNumFrame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageButton
                    android:id="@+id/NineNum"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_white_round"
                    android:layout_marginStart="20dp"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="11dp"
                    android:padding="8dp"
                    android:text="9"
                    android:textColor="@android:color/black"
                    android:textSize="28dp"
                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4" />

            </FrameLayout>

            <FrameLayout
                android:id="@+id/MultiplyFrame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageView
                    android:id="@+id/Multiply"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_grey_round"
                    android:layout_marginStart="20dp"
                    android:scaleType="centerInside"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="11dp"
                    android:padding="8dp"
                    android:text="✖️"
                    android:textColor="@android:color/black"
                    android:textSize="28dp"
                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4" />
            </FrameLayout>

        </LinearLayout>

        <!-- 4 5 6 -      -->
        <LinearLayout
            android:id="@+id/Three"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:paddingTop="15dp"
            >
            <FrameLayout
                android:id="@+id/FourNumFrame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageButton
                    android:id="@+id/FourNum"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_white_round"
                    android:layout_marginStart="20dp"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="11dp"
                    android:padding="8dp"
                    android:text="4"
                    android:textColor="@android:color/black"
                    android:textSize="28dp"
                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4" />
            </FrameLayout>

            <FrameLayout
                android:id="@+id/FiveNumFrame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageButton
                    android:id="@+id/FiveNum"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_white_round"
                    android:layout_marginStart="20dp"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="11dp"
                    android:padding="8dp"
                    android:text="5"
                    android:textColor="@android:color/black"
                    android:textSize="28dp"
                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4" />
            </FrameLayout>

            <FrameLayout
                android:id="@+id/SixNumFrame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageButton
                    android:id="@+id/SixNum"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_white_round"
                    android:layout_marginStart="20dp"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="11dp"
                    android:padding="8dp"
                    android:text="6"
                    android:textColor="@android:color/black"
                    android:textSize="28dp"
                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4" />
            </FrameLayout>

            <FrameLayout
                android:id="@+id/BubFrame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageButton
                    android:id="@+id/Sub"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_grey_round"
                    android:layout_marginStart="20dp"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="11dp"
                    android:padding="8dp"
                    android:text=""
                    android:textColor="@android:color/black"
                    android:textSize="28dp"
                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4" />
            </FrameLayout>


        </LinearLayout>

        <!-- 1 2 3 +      -->
        <LinearLayout
            android:id="@+id/Four"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:paddingTop="15dp"
            >
            <FrameLayout
                android:id="@+id/OneNumFrame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageButton
                    android:id="@+id/OneNum"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_white_round"
                    android:layout_marginStart="20dp"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="11dp"
                    android:padding="8dp"
                    android:text="1"
                    android:textColor="@android:color/black"
                    android:textSize="28dp"
                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4" />
            </FrameLayout>

            <FrameLayout
                android:id="@+id/TwoNumFrame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageButton
                    android:id="@+id/TwoNum"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_white_round"
                    android:layout_marginStart="20dp"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="11dp"
                    android:padding="8dp"
                    android:text="2"
                    android:textColor="@android:color/black"
                    android:textSize="28dp"
                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4" />
            </FrameLayout>

            <FrameLayout
                android:id="@+id/ThreeNumFrame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageButton
                    android:id="@+id/ThreeNum"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_white_round"
                    android:layout_marginStart="20dp"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="11dp"
                    android:padding="8dp"
                    android:text="3"
                    android:textColor="@android:color/black"
                    android:textSize="28dp"
                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4" />
            </FrameLayout>

            <FrameLayout
                android:id="@+id/AddFrame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageButton
                    android:id="@+id/add"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_grey_round"
                    android:layout_marginStart="20dp"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="11dp"
                    android:padding="8dp"
                    android:text=""
                    android:textColor="@android:color/black"
                    android:textSize="28dp"
                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4" />
            </FrameLayout>


        </LinearLayout>

        <!-- 00 0 . =      -->
        <LinearLayout
            android:id="@+id/Five"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:paddingTop="15dp"
            >
            <FrameLayout
                android:id="@+id/CFrame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageButton
                    android:id="@+id/C"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_white_round"
                    android:layout_marginStart="20dp"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="C"
                    android:textSize="25sp"
                    android:textColor="@android:color/black"
                    android:layout_gravity="center"
                    android:layout_marginLeft="10dp"
                    android:padding="8dp"
                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4"/>
            </FrameLayout>

            <FrameLayout
                android:id="@+id/ONumFrame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageButton
                    android:id="@+id/O"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_white_round"
                    android:layout_marginStart="20dp"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="11dp"
                    android:padding="8dp"
                    android:text="0"
                    android:textColor="@android:color/black"
                    android:textSize="28dp"
                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4" />
            </FrameLayout>

            <FrameLayout
                android:id="@+id/PointFrame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageButton
                    android:id="@+id/Point"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_white_round"
                    android:layout_marginStart="20dp"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="11dp"
                    android:paddingBottom="10dp"
                    android:text="."
                    android:textColor="@android:color/black"
                    android:textSize="28dp"
                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4" />
            </FrameLayout>

            <FrameLayout
                android:id="@+id/equalFrame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <ImageButton
                    android:id="@+id/equal"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_orange_round"
                    android:layout_marginStart="20dp"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="11dp"
                    android:paddingBottom="15dp"
                    android:text=""
                    android:textColor="@android:color/white"
                    android:textSize="45dp"
                    android:shadowColor="#80000000"
                    android:shadowDx="2"
                    android:shadowDy="2"
                    android:shadowRadius="4" />
            </FrameLayout>

        </LinearLayout>

    </LinearLayout>

</LinearLayout>

我们简单分解一下代码中的重点

1.1 给文本制作阴影并加粗

<TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="("
          android:textSize="25sp"
          android:textColor="@android:color/black"
          android:layout_gravity="center"
          android:layout_marginLeft="10dp"
          android:padding="8dp"
          android:shadowColor="#80000000"
          android:shadowDx="2"
          android:shadowDy="2"
          android:shadowRadius="4"
          android:textStyle="bold/>
  1. android:shadowColor="#80000000":表示为该视图的文本添加阴影效果,阴影颜色为半透明黑色(#80000000)。
  2. android:shadowDx="2":表示阴影在水平方向上的偏移量为2个像素。
  3. android:shadowDy="2":表示阴影在垂直方向上的偏移量为2个像素。
  4. android:shadowRadius="4":表示阴影的模糊半径为4个像素。
  5. android:textStyle="bold":是对TextView(文本视图)的一个属性设置,用于指定文本的字体样式为粗体(加粗)。

2.2 制作圆形按钮

在drawable目录下新建xml文件如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="@color/orange" />
    <size android:height="60dp" android:width="60dp"/>
</shape>

android:shape指定图形,常用参数有:

  1. "rectangle": 表示创建一个矩形的形状。
  2. "oval": 表示创建一个椭圆的形状,也就是圆形。
  3. "line": 表示创建一条线段的形状。
  4. "ring": 表示创建一个圆环的形状。
  5. "line": 表示创建一条线段的形状。

solid:用于填充颜色

**size **:用于指定大小,因为是圆形我们这里长宽都要设置为相同

效果如下:

制作一个简易的计算器app,Android,android,开发语言,java,xml

2.3 制作点击变色的按钮

笔者在这里,没有使用点击变色而是使用了动画,后面介绍动画。这里介绍一下怎么点击变色。

首先还是在drawable目录下新建一个xml文件

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 定义按下状态的样式 -->
<item android:state_pressed="true">
    <shape android:shape="oval">
        <solid android:color="@color/Greywhite" />
        <size android:height="60dp" android:width="60dp"/>
    </shape>
</item>
<!-- 定义普通状态的样式 -->
<item>
    <shape android:shape="oval">
        <solid android:color="@color/Greywhite4" />
        <size android:height="60dp" android:width="60dp"/>
    </shape>
</item>
</selector>

设置一个selector,如何设置两个item选项,设置为android:state_pressed="true"的选项在点击后就会产生对应的变化。

2、点击事件与界面处理

1、禁用输入法修改EditText文本内容

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        activityMainBinding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(activityMainBinding.getRoot());

        //禁用输入法修改EditText文本内容
        activityMainBinding.ScanfEditText.setInputType(InputType.TYPE_NULL);

        //传入各个按键
        //功能键
        activityMainBinding.C.setOnClickListener(this);
        activityMainBinding.DeleteOne.setOnClickListener(this);

        //加减乘除,括号,等于
        activityMainBinding.add.setOnClickListener(this);
        activityMainBinding.Sub.setOnClickListener(this);
        activityMainBinding.Multiply.setOnClickListener(this);
        activityMainBinding.Division.setOnClickListener(this);
        activityMainBinding.leftC.setOnClickListener(this);
        activityMainBinding.RightC.setOnClickListener(this);
        activityMainBinding.equal.setOnClickListener(this);

        //数字,小数点
        activityMainBinding.O.setOnClickListener(this);
        activityMainBinding.OneNum.setOnClickListener(this);
        activityMainBinding.TwoNum.setOnClickListener(this);
        activityMainBinding.ThreeNum.setOnClickListener(this);
        activityMainBinding.FourNum.setOnClickListener(this);
        activityMainBinding.FiveNum.setOnClickListener(this);
        activityMainBinding.SixNum.setOnClickListener(this);
        activityMainBinding.SevenNum.setOnClickListener(this);
        activityMainBinding.EightNum.setOnClickListener(this);
        activityMainBinding.NineNum.setOnClickListener(this);
        activityMainBinding.Point.setOnClickListener(this);


        activityMainBinding.TwoArrowsShrink.setOnClickListener(this);

        //长按触发菜单
        registerForContextMenu(activityMainBinding.ThreePoints);


    }
        activityMainBinding.ScanfEditText.setInputType(InputType.TYPE_NULL);

通过设置 InputType.TYPE_NULLEditText 将不再响应输入法的输入,用户无法通过软键盘输入文本内容。这样做的目的通常是为了限制用户只能通过其他途径(比如扫码、点击按钮等)来输入文本内容,而不能直接通过键盘输入。如何我们为每个按钮注册监听事件

2、按键缩放动画和实现震动效果

    private void animation(View view) {
        // 加载缩放动画资源
        final AnimatorSet scaleAnimation = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.scale_animation);

        //实现震动效果
        /**
         *         Vibrator vibrator=(Vibrator)getSystemService(Service.VIBRATOR_SERVICE);
         *         vibrator.vibrate(new long[]{0,100}, -1);
         * 从Android API level 26开始,Vibrator类的vibrate()方法被弃用,推荐使用VibrationEffect来实现震动效果。VibrationEffect类提供了更灵活和可控的震动方式。
         */
        // 获取Vibrator实例
        Vibrator vibrator = (Vibrator) getSystemService(Service.VIBRATOR_SERVICE);

        // 判断Android版本是否大于等于API 26
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // 创建VibrationEffect对象,指定震动模式和震动时长100ms
            VibrationEffect vibrationEffect = VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE);
            // 开始震动
            vibrator.vibrate(vibrationEffect);
        } else {
            // Android版本低于API 26,使用老版本的vibrate方法
            //震动时间为100ms
            vibrator.vibrate(100);
        }

        // 开始执行缩放动画
        scaleAnimation.setTarget(view);
        scaleAnimation.start();

        scaleAnimation.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {

                // 在缩放动画结束时,创建还原动画并执行还原动画
                ObjectAnimator restoreAnimationX = ObjectAnimator.ofFloat(view, "scaleX", 1.0f);
                ObjectAnimator restoreAnimationY = ObjectAnimator.ofFloat(view, "scaleY", 1.0f);
                AnimatorSet restoreAnimation = new AnimatorSet();
                restoreAnimation.playTogether(restoreAnimationX, restoreAnimationY);
                restoreAnimation.start();
            }
        });
    }

首先加载缩放动画资源。

final AnimatorSet scaleAnimation = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.scale_animation);

scale_animationanimator下设置的动画属性

具体设置如下:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:propertyName="scaleX"
        android:valueFrom="1.0"
        android:valueTo="0.9"
        android:duration="100"
        android:repeatCount="0"
        android:repeatMode="restart"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator" />
    <objectAnimator
        android:propertyName="scaleY"
        android:valueFrom="1.0"
        android:valueTo="0.9"
        android:duration="100"
        android:repeatCount="0"
        android:repeatMode="restart"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator" />
</set>
  1. android:propertyName: 定义要动画化的属性的名称。在这里,scaleXscaleY 分别表示水平和垂直方向的缩放。
  2. android:valueFrom: 定义动画的起始值。这里起始值为 1.0,表示不缩放。
  3. android:valueTo: 定义动画的结束值。这里结束值为 0.9,表示缩放到原始大小的 0.9 倍。
  4. android:duration: 定义动画的持续时间,以毫秒为单位。这里持续时间为 100 毫秒,即缩放动画的过程为 0.1 秒。
  5. android:repeatCount: 定义动画重复的次数。这里设置为 0,表示动画不重复。
  6. android:repeatMode: 定义动画重复的模式。这里设置为 restart,表示每次重复动画都从头开始。
  7. android:interpolator: 定义动画的插值器,用于控制动画的变化速率。这里使用了 Android 系统自带的 accelerate_decelerate_interpolator 插值器,表示动画先加速后减速。

这个 XML 文件定义了两个属性动画,分别是在水平方向和垂直方向上的缩放动画效果。在 Android 应用中,你可以通过加载这个 XML 文件来应用这个缩放动画,让指定的视图(如 ViewImageView)在缩放动画的作用下,由原始大小缩放到 0.9 倍的大小。

制作动画时,创建了一个 scaleAnimation 缩放动画,然后给该动画添加了一个监听器 AnimatorListenerAdapter。在监听器的 onAnimationEnd() 方法中,当缩放动画结束时,会执行还原动画。

大致逻辑:

  1. 创建缩放动画 scaleAnimation 并设置属性动画的相关参数。
  2. scaleAnimation 添加一个监听器,在缩放动画结束时执行还原动画。
  3. 创建两个 ObjectAnimator 分别对 viewscaleXscaleY 属性进行动画处理,将 view 的缩放比例恢复为原始大小(1.0f)。
  4. 将还原动画 restoreAnimation 中的两个动画一起播放。

3、实现显示框字体大小变化的动画

当我们计算完结果后,我们让计算的结果变大,计算的算式变小

private void DisplayFrameAnimation(View Little_big, View Big_little) {        
    // 加载动画资源,从25变到40
    AnimatorSet Little_Big = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.text_size_25_40);
    // 设置目标视图
    Little_Big.setTarget(Little_big);
    // 启动动画
    Little_Big.start();

    // 加载动画资源,从40变到25
    AnimatorSet Big_Little = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.text_size_40_25);
    // 设置目标视图
    Big_Little.setTarget(Big_little);
    // 启动动画
    Big_Little.start();
}

AnimatorInflater: 这是一个用于加载属性动画的类。它提供了一个方法 loadAnimator(),可以通过指定资源ID加载属性动画。

  1. this: 这里的 this 指的是当前的上下文,即所在的 Activity
  2. R.animator.text_size_40_25: 这是指定的属性动画资源的资源ID。在这里,text_size_40_25 是一个位于 res/animator 目录下的 XML 文件,它定义了一组属性动画。

同样这样的操作需要动画文件,我们在这里介绍一下字体大小由25变化到40的

<?xml version="1.0" encoding="utf-8"?>
<!-- text_size_change.xml -->
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:propertyName="textSize"
        android:valueType="floatType"
        android:valueFrom="25"
        android:valueTo="40"
        android:duration="500"
        />
</set>
  1. <set>:这是属性动画的根元素,用于定义属性动画集合。在这里,我们只有一个动画,所以只有一个 <objectAnimator> 子元素。
  2. <objectAnimator>:这是一个对象动画元素,用于定义属性动画。它有以下属性:
    • android:propertyName="textSize":这是要动画化的属性名称,即视图的文本大小属性 textSize
    • android:valueType="floatType":这是动画值的类型,这里是浮点数类型,用于表示文本大小。
    • android:valueFrom="25":这是动画的起始值,即文本大小的初始值为 25。
    • android:valueTo="40":这是动画的结束值,即文本大小的目标值为 40。
    • android:duration="500":这是动画的持续时间,即从起始值到结束值的过渡时间为 500 毫秒。

3、逻辑与算法

1.1 按钮点击结果的分析与处理

package com.example.computermoblie;

import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Service;
import android.os.Build;
import android.os.Bundle;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.text.InputType;
import android.util.Log;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.example.computermoblie.databinding.ActivityMainBinding;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    // 计算器储存总数据的上限
    public List<String> SumNumber = new ArrayList<>();

    //计算器存储的数字上限
    private StringBuilder Number = new StringBuilder();


    //当前输入框字体大小,初始状态为40dp
    private int SIzeOfText = 40;

    public ActivityMainBinding activityMainBinding;

    private boolean GetEqual = false;    //表示没有按下等号

    private boolean NegativeSymbol = false; //表示不是负数的符号

    public String ret; //运算结果

    private static final String Del = "Delete"; //表示删除键

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        activityMainBinding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(activityMainBinding.getRoot());

        //禁用输入法修改EditText文本内容
        activityMainBinding.ScanfEditText.setInputType(InputType.TYPE_NULL);

        //传入各个按键
        //功能键
        activityMainBinding.C.setOnClickListener(this);
        activityMainBinding.DeleteOne.setOnClickListener(this);

        //加减乘除,括号,等于
        activityMainBinding.add.setOnClickListener(this);
        activityMainBinding.Sub.setOnClickListener(this);
        activityMainBinding.Multiply.setOnClickListener(this);
        activityMainBinding.Division.setOnClickListener(this);
        activityMainBinding.leftC.setOnClickListener(this);
        activityMainBinding.RightC.setOnClickListener(this);
        activityMainBinding.equal.setOnClickListener(this);

        //数字,小数点
        activityMainBinding.O.setOnClickListener(this);
        activityMainBinding.OneNum.setOnClickListener(this);
        activityMainBinding.TwoNum.setOnClickListener(this);
        activityMainBinding.ThreeNum.setOnClickListener(this);
        activityMainBinding.FourNum.setOnClickListener(this);
        activityMainBinding.FiveNum.setOnClickListener(this);
        activityMainBinding.SixNum.setOnClickListener(this);
        activityMainBinding.SevenNum.setOnClickListener(this);
        activityMainBinding.EightNum.setOnClickListener(this);
        activityMainBinding.NineNum.setOnClickListener(this);
        activityMainBinding.Point.setOnClickListener(this);


        activityMainBinding.TwoArrowsShrink.setOnClickListener(this);

        //长按触发菜单
        registerForContextMenu(activityMainBinding.ThreePoints);


    }

    @Override
    public void onClick(View view) {
        final int Id = view.getId();
        // 调用按键动画
        animation(view);

        //退出
        if(Id == R.id.TwoArrows_Shrink){
            finish();
        }


        //功能按钮
        if (Id == R.id.C) {
            //清空显示
            activityMainBinding.ScanfEditText.setText("");
            ret = "";
            activityMainBinding.PrintfText.setText(ret);

            //清空储存的内容
            SumNumber.clear();
            Number.setLength(0);

            //还原字体大小
            SIzeOfText = 40;

        } else {
            if (Id == R.id.leftC) {

                if (!GetEqual) {
                    if (Number.length() > 0) {
                        char cat = Number.charAt(Number.length() - 1);
                        if (cat != '.' && !Character.isDigit(cat)) {
                            SumNumber.add("(");

                        } else {
                            //左括号前面没有符号只有数字默认为乘号
                            //将number的数据放入Sumnumber
                            if (!Number.equals("") && Number != null) {
                                //保存数据
                                try {
                                    SumNumber.add(String.valueOf(Number));
                                } catch (NumberFormatException e) {
                                    Log.d("Number", "出现空值");
                                }

                            }
                            Number.setLength(0);
                            SumNumber.add("×");
                            SumNumber.add("(");
                        }
                    } else if (!SumNumber.isEmpty()) {
                        //判断是不是存在两个相邻的操作
                        String str = SumNumber.get(SumNumber.size() - 1);
                        if (!str.equals("+") && !str.equals("-") && !str.equals("×") && !str.equals("÷") && !str.equals("(")) {
                            SumNumber.add("×");
                            SumNumber.add("(");
                        } else {
                            SumNumber.add("(");
                        }
                    }

                    //开头就使用括号的情况
                    if (SumNumber.isEmpty()){
                        SumNumber.add("(");
                    }
                }
            }

            if (Id == R.id.RightC) {
                if (!GetEqual) {
                    if (Number.length() > 0) {
                        char cat = Number.charAt(Number.length() - 1);
                        if (cat != '.') {
                            //将number的数据放入Sumnumber
                            if (!Number.equals("") && Number != null) {
                                //保存数据
                                try {
                                    SumNumber.add(String.valueOf(Number));
                                } catch (NumberFormatException e) {
                                    Log.d("Number", "出现空值");
                                }

                            }
                            Number.setLength(0);
                            SumNumber.add(")");

                            //使得按下后动态计算结果
                            DynamicCalculation();
                        }
                    } else if (!SumNumber.isEmpty()) {
                        //判断是不是存在两个相邻的操作
                        String str = SumNumber.get(SumNumber.size() - 1);
                        Log.d("DEL1", SumNumber.toString());
                        if (!str.equals("+") && !str.equals("-") && !str.equals("×") && !str.equals("÷") && !str.equals("(")) {
                            SumNumber.add(")");
                            //使得按下后动态计算结果
                            DynamicCalculation();
                        }
                    }
                }
            }

            if (Id == R.id.DeleteOne) {
                if (!GetEqual) {
                    if (Number.length() > 0) {
                        Number.deleteCharAt(Number.length() - 1);
                    } else if (SumNumber.size() > 0) {
                        try {
                            Number.setLength(0);
                            Number.append(SumNumber.remove(SumNumber.size() - 1));
                            Number.deleteCharAt(Number.length() - 1);
                        }catch (NumberFormatException e){
                            Log.d("Number", "出现空值");
                        }
                    }else {
                        ret = "";
                        activityMainBinding.PrintfText.setText(ret);
                    }

                    //删除所有数据后清除结果
                    if (SumNumber.isEmpty()){
                        ListComputing(Del);
                    }
                }else {
                    ListComputing(Del);
                }

                //使得按下后动态计算结果
                DynamicCalculation();
            }

            //加减乘除
            if (Id == R.id.add) {
                if (!GetEqual) {
                    if (Number.length() > 0) {
                        if (Number.charAt(Number.length() - 1) != '.') {
                            //将number的数据放入Sumnumber
                            if (!Number.equals("") && Number != null) {
                                //保存数据
                                try {
                                    SumNumber.add(String.valueOf(Number));
                                } catch (NumberFormatException e) {
                                    Log.d("Number", "出现空值");
                                }

                            }

                            Number.setLength(0);
                            SumNumber.add("+");
                        }
                    } else if (!SumNumber.isEmpty()) {
                        //判断是不是存在两个相邻的操作
                        String str = SumNumber.get(SumNumber.size() - 1);
                        if (!str.equals("+") && !str.equals("-") && !str.equals("×") && !str.equals("÷") && !str.equals("(")) {
                            //将number的数据放入Sumnumber
                            if (!Number.equals("") && Number != null) {
                                //保存数据
                                try {
                                    SumNumber.add(String.valueOf(Number));
                                } catch (NumberFormatException e) {
                                    Log.d("Number", "出现空值");
                                }

                            }

                            Log.d("String1", String.valueOf(Number));
                            Number.setLength(0);
                            SumNumber.add("+");
                        }
                    }
                } else {
                    ListComputing("+");
                }
            }

            if (Id == R.id.Sub) {
                if (!GetEqual) {
                    if (Number.length() > 0) {
                        if (Number.charAt(Number.length() - 1) != '.') {
                            //将number的数据放入Sumnumber
                            if (!Number.equals("") && Number != null) {
                                //保存数据
                                try {
                                    SumNumber.add(String.valueOf(Number));
                                } catch (NumberFormatException e) {
                                    Log.d("Number", "出现空值");
                                }

                            }

                            Log.d("String1", String.valueOf(Number));
                            Number.setLength(0);
                            SumNumber.add("-");
                        }
                    } else if (!SumNumber.isEmpty()) {
                        //判断是不是存在两个相邻的操作
                        String str = SumNumber.get(SumNumber.size() - 1);
                        if (!str.equals("+") && !str.equals("-") && !str.equals("×") && !str.equals("÷") && !str.equals("(")) {
                            //将number的数据放入Sumnumber
                            if (!Number.equals("") && Number != null) {
                                //保存数据
                                try {
                                    SumNumber.add(String.valueOf(Number));
                                } catch (NumberFormatException e) {
                                    Log.d("Number", "出现空值");
                                }

                            }

                            Log.d("String1", String.valueOf(Number));
                            Number.setLength(0);
                            SumNumber.add("-");
                        } else if (str.equals("×") || str.equals("÷")||str.equals("(")) {
                            Number.append("-");
                        }
                    }else {
                        Number.append("-");
                    }
                } else {
                    ListComputing("-");
                }
            }

            if (Id == R.id.Multiply) {
                if (!GetEqual) {
                    if (Number.length() > 0) {
                        if (Number.charAt(Number.length() - 1) != '.') {
                            //将number的数据放入Sumnumber
                            if (!Number.equals("") && Number != null) {
                                //保存数据
                                try {
                                    SumNumber.add(String.valueOf(Number));
                                } catch (NumberFormatException e) {
                                    Log.d("Number", "出现空值");
                                }

                            }

                            Log.d("String1", String.valueOf(Number));
                            Number.setLength(0);
                            SumNumber.add("×");
                        }
                    } else if (!SumNumber.isEmpty()) {
                        //判断是不是存在两个相邻的操作
                        String str = SumNumber.get(SumNumber.size() - 1);
                        if (!str.equals("+") && !str.equals("-") && !str.equals("×") && !str.equals("÷") && !str.equals("(")) {
                            //将number的数据放入Sumnumber
                            if (!Number.equals("") && Number != null) {
                                //保存数据
                                try {
                                    SumNumber.add(String.valueOf(Number));
                                } catch (NumberFormatException e) {
                                    Log.d("Number", "出现空值");
                                }

                            }

                            Log.d("String1", String.valueOf(Number));
                            Number.setLength(0);
                            SumNumber.add("×");
                        }
                    }
                } else {
                    ListComputing("×");
                }
            }

            if (Id == R.id.Division) {
                if (!GetEqual) {

                    if (Number.length() > 0) {
                        if (Number.charAt(Number.length() - 1) != '.') {
                            //将number的数据放入Sumnumber
                            if (!Number.equals("") && Number != null) {
                                //保存数据
                                try {
                                    SumNumber.add(String.valueOf(Number));
                                } catch (NumberFormatException e) {
                                    Log.d("Number", "出现空值");
                                }

                            }

                            Log.d("String1", String.valueOf(Number));
                            Number.setLength(0);
                            SumNumber.add("÷");
                        }
                    } else if (!SumNumber.isEmpty()) {
                        //判断是不是存在两个相邻的操作
                        String str = SumNumber.get(SumNumber.size() - 1);
                        if (!str.equals("+") && !str.equals("-") && !str.equals("×") && !str.equals("÷") && !str.equals("(")) {
                            //将number的数据放入Sumnumber
                            if (!Number.equals("") && Number != null) {
                                //保存数据
                                try {
                                    SumNumber.add(String.valueOf(Number));
                                } catch (NumberFormatException e) {
                                    Log.d("Number", "出现空值");
                                }

                            }

                            Log.d("String1", String.valueOf(Number));
                            Number.setLength(0);
                            SumNumber.add("÷");
                        }
                    }
                } else {
                    ListComputing("÷");
                }
            }

            //数字
            if (Id == R.id.OneNum) {
                ClearDisplay();//清空显示
                if (!SumNumber.isEmpty()) {
                    String str = SumNumber.get(SumNumber.size() - 1);
                    if (str.equals(")")) {
                        SumNumber.add("×");
                    }
                }
                Number.append("1");

//                //使得按下数字后动态计算结果
                DynamicCalculation();
            }

            if (Id == R.id.TwoNum) {
                ClearDisplay();//清空显示
                if (!SumNumber.isEmpty()) {
                    String str = SumNumber.get(SumNumber.size() - 1);
                    if (str.equals(")")) {
                        SumNumber.add("×");
                    }
                }
                Number.append("2");

//                //使得按下数字后动态计算结果
                DynamicCalculation();
            }

            if (Id == R.id.ThreeNum) {
                ClearDisplay();//清空显示
                if (!SumNumber.isEmpty()) {
                    String str = SumNumber.get(SumNumber.size() - 1);
                    if (str.equals(")")) {
                        SumNumber.add("×");
                    }
                }
                Number.append("3");

//                //使得按下数字后动态计算结果
                DynamicCalculation();
            }

            if (Id == R.id.FourNum) {
                ClearDisplay();//清空显示
                if (!SumNumber.isEmpty()) {
                    String str = SumNumber.get(SumNumber.size() - 1);
                    if (str.equals(")")) {
                        SumNumber.add("×");
                    }
                }
                Number.append("4");

//                //使得按下数字后动态计算结果
                DynamicCalculation();
            }
            if (Id == R.id.FiveNum) {
                ClearDisplay();//清空显示
                if (!SumNumber.isEmpty()) {
                    String str = SumNumber.get(SumNumber.size() - 1);
                    if (str.equals(")")) {
                        SumNumber.add("×");
                    }
                }
                Number.append("5");

//                //使得按下数字后动态计算结果
                DynamicCalculation();
            }

            if (Id == R.id.SixNum) {
                ClearDisplay();//清空显示
                if (!SumNumber.isEmpty()) {
                    String str = SumNumber.get(SumNumber.size() - 1);
                    if (str.equals(")")) {
                        SumNumber.add("×");
                    }
                }
                Number.append("6");

//                //使得按下数字后动态计算结果
                DynamicCalculation();
            }

            if (Id == R.id.SevenNum) {
                ClearDisplay();//清空显示
                if (!SumNumber.isEmpty()) {
                    String str = SumNumber.get(SumNumber.size() - 1);
                    if (str.equals(")")) {
                        SumNumber.add("×");
                    }
                }
                Number.append("7");

//                //使得按下数字后动态计算结果
                DynamicCalculation();
            }

            if (Id == R.id.EightNum) {
                ClearDisplay();//清空显示
                if (!SumNumber.isEmpty()) {
                    String str = SumNumber.get(SumNumber.size() - 1);
                    if (str.equals(")")) {
                        SumNumber.add("×");
                    }
                }
                Number.append("8");

//                //使得按下数字后动态计算结果
                DynamicCalculation();
            }
            if (Id == R.id.NineNum) {
                ClearDisplay();//清空显示
                if (!SumNumber.isEmpty()) {
                    String str = SumNumber.get(SumNumber.size() - 1);
                    if (str.equals(")")) {
                        SumNumber.add("×");
                    }
                }
                Number.append("9");

                //使得按下数字后动态计算结果
                DynamicCalculation();
            }
            if (Id == R.id.O) {
                ClearDisplay();//清空显示
                if (!SumNumber.isEmpty()) {
                    String str = SumNumber.get(SumNumber.size() - 1);
                    if (str.equals(")")) {
                        SumNumber.add("×");
                    }
                }
                Number.append("0");

                //使得按下数字后动态计算结果
                DynamicCalculation();
            }


            if (Id == R.id.Point) {
                if (Number.length() > 0) {
                    int t = 0;
                    for (int i = 0; i < Number.length(); i++) {
                        if (Number.charAt(i) == '.') {
                            t++;
                        }
                    }
                    if (t < 1) {
                        Number.append(".");
                    }
                }
            }

            if (Id == R.id.equal) {
                if (Number.length() > 0) {
                    if (Number.charAt(Number.length() - 1) != '.') {
                        //将number的数据放入Sumnumber
                        if (!Number.equals("") && Number != null) {
                            //保存数据
                            try {
                                SumNumber.add(String.valueOf(Number));
                            } catch (NumberFormatException e) {
                                Log.d("Number", "出现空值");
                            }

                        }

                        Number.setLength(0);

                        //表示等号已经按下,用于清除文本框
                        GetEqual = true;

                        //计算结果
                        ReversePolish reversePolish = new ReversePolish(SumNumber);
                        ret = reversePolish.EvaluatePostfixExpressions();
                        //加载大小变化的动画
                        DisplayFrameAnimation(activityMainBinding.PrintfText, activityMainBinding.ScanfEditText);
                    }
                } else if (!SumNumber.isEmpty()) {
                    //判断是不是存在两个相邻的操作
                    String str = SumNumber.get(SumNumber.size() - 1);
                    if (str.equals(")")) {
                        //将number的数据放入Sumnumber
                        if (!Number.equals("") && Number != null) {
                            //保存数据
                            try {
                                SumNumber.add(String.valueOf(Number));
                            } catch (NumberFormatException e) {
                                Log.d("Number", "出现空值");
                            }

                        }

                        Number.setLength(0);

                        //表示等号已经按下,用于清除文本框
                        GetEqual = true;

                        //计算结果
                        ReversePolish reversePolish = new ReversePolish(SumNumber);
                        ret = reversePolish.EvaluatePostfixExpressions();

                        //加载大小变化的动画
                        DisplayFrameAnimation(activityMainBinding.PrintfText, activityMainBinding.ScanfEditText);
                    }
                }
            }

            //显示文本框内容
            if (Number != null) {
                StringBuilder builder = new StringBuilder();
                for (String str : SumNumber) {
                    builder.append(str);
                }
                builder.append(Number);
                activityMainBinding.ScanfEditText.setText(builder);
                activityMainBinding.PrintfText.setText(ret);
                MaxDisplayFrameAnimation(activityMainBinding.ScanfEditText);
            }

        }


    }

    //按键缩放动画和实现震动效果
    private void animation(View view) {
        // 加载缩放动画资源
        final AnimatorSet scaleAnimation = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.scale_animation);

        //实现震动效果
        /**
         *         Vibrator vibrator=(Vibrator)getSystemService(Service.VIBRATOR_SERVICE);
         *         vibrator.vibrate(new long[]{0,100}, -1);
         * 从Android API level 26开始,Vibrator类的vibrate()方法被弃用,推荐使用VibrationEffect来实现震动效果。VibrationEffect类提供了更灵活和可控的震动方式。
         */
        // 获取Vibrator实例
        Vibrator vibrator = (Vibrator) getSystemService(Service.VIBRATOR_SERVICE);

        // 判断Android版本是否大于等于API 26
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // 创建VibrationEffect对象,指定震动模式和震动时长
            VibrationEffect vibrationEffect = VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE);
            // 开始震动
            vibrator.vibrate(vibrationEffect);
        } else {
            // Android版本低于API 26,使用老版本的vibrate方法
            vibrator.vibrate(100);
        }

        // 开始执行缩放动画
        scaleAnimation.setTarget(view);
        scaleAnimation.start();

        scaleAnimation.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {

                // 在缩放动画结束时,创建还原动画并执行还原动画
                ObjectAnimator restoreAnimationX = ObjectAnimator.ofFloat(view, "scaleX", 1.0f);
                ObjectAnimator restoreAnimationY = ObjectAnimator.ofFloat(view, "scaleY", 1.0f);
                AnimatorSet restoreAnimation = new AnimatorSet();
                restoreAnimation.playTogether(restoreAnimationX, restoreAnimationY);
                restoreAnimation.start();
            }
        });
    }


    // 显示框的动画效果
    private void DisplayFrameAnimation(View Little_big, View Big_little) {

        /**
         * SIzeOfText == 40 由上方40-25 下方25-40
         * SIzeOfText == 30 由上方30-25 下方25-30
         * SIzeOfText == 25 由上方不变 下方25-30
         */


        if (SIzeOfText == 40) {
            // 加载动画资源,从25变到40
            AnimatorSet Little_Big = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.text_size_25_40);
            // 设置目标视图
            Little_Big.setTarget(Little_big);
            // 启动动画
            Little_Big.start();

            // 加载动画资源,从40变到25
            AnimatorSet Big_Little = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.text_size_40_25);
            // 设置目标视图
            Big_Little.setTarget(Big_little);
            // 启动动画
            Big_Little.start();
        } else if (SIzeOfText == 30) {
            Log.d("SIzeOfText", String.valueOf(SIzeOfText));

            // 加载动画资源,从25变到30
            AnimatorSet Little_Big = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.text_size_25_30);
            // 设置目标视图
            Little_Big.setTarget(Little_big);
            // 启动动画
            Little_Big.start();

            // 加载动画资源,从30变到25
            AnimatorSet Big_Little = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.text_size_30_25);
            // 设置目标视图
            Big_Little.setTarget(Big_little);
            // 启动动画
            Big_Little.start();
        } else if (SIzeOfText == 25) {
            // 加载动画资源,从25变到30
            AnimatorSet Little_Big = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.text_size_25_30);
            // 设置目标视图
            Little_Big.setTarget(Little_big);
            // 启动动画
            Little_Big.start();
        }

    }

    //显示框的字符达到指定长度使得一行无法放下
    private void MaxDisplayFrameAnimation(View Big_littleView) {
        int MaxDigit = 0;
        for (String str : SumNumber) {
            MaxDigit += str.length();
        }

        MaxDigit += Number.length();

        Log.d("StrSize", "num:" + MaxDigit);
        if (MaxDigit == 10) {

            SIzeOfText = 30;    //字体变化为30

            // 加载动画资源,从40变到30
            AnimatorSet Big_Little = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.text_size_40_30);
            // 设置目标视图
            Big_Little.setTarget(Big_littleView);
            // 启动动画
            Big_Little.start();

        }
        if (MaxDigit > 10 && MaxDigit < 25) activityMainBinding.ScanfEditText.setTextSize(30);

        if (MaxDigit == 15) {

            SIzeOfText = 25;    //字体变化为25

            // 加载动画资源,从30变到25
            AnimatorSet Big_Little = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.text_size_30_25);
            // 设置目标视图
            Big_Little.setTarget(Big_littleView);

            // 启动动画
            Big_Little.start();


            activityMainBinding.ScanfEditText.setTextSize(25);
        }
        if (MaxDigit > 15) activityMainBinding.ScanfEditText.setTextSize(25);

    }


    //加载菜单
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        Log.d("Tag", "加载菜单");
        getMenuInflater().inflate(R.menu.function, menu);
        super.onCreateContextMenu(menu, v, menuInfo);
    }

    //注册菜单点击事件
    @Override
    public boolean onContextItemSelected(@NonNull MenuItem item) {
        Log.d("Tag", "点击事件");
        final int Id = item.getItemId();


        if (Id == R.id.Log) {
            //历史记录

        } else if (Id == R.id.SetUp) {
            //设置

        }

        return super.onContextItemSelected(item);
    }

    //清空显示
    private void ClearDisplay() {

        //还原显示框大小
        activityMainBinding.ScanfEditText.setTextSize(40);
        activityMainBinding.PrintfText.setTextSize(30);

        //表示已经按下=后,重新输入数字的情况
        if (GetEqual) {
            GetEqual = false;
            activityMainBinding.ScanfEditText.setText("");
            ret = "";
            //清空储存的内容
            SumNumber.clear();
            Number.setLength(0);

            //还原字体大小
            SIzeOfText = 40;
        }
    }

    //连续计算的情况
    private void ListComputing(String str) {

        if (str.equals(Del)) {
            GetEqual = false;

            //还原显示框大小
            activityMainBinding.ScanfEditText.setTextSize(40);
            activityMainBinding.PrintfText.setTextSize(30);

            SIzeOfText = 40;

            ret = "";

            if (Number.length() > 0) {
                Number.deleteCharAt(Number.length() - 1);
            } else if (SumNumber.size() > 0) {
                try {
                    Number.setLength(0);
                    Number.append(SumNumber.remove(SumNumber.size() - 1));
                    Number.deleteCharAt(Number.length() - 1);
                }catch (NumberFormatException e){
                    Log.d("Number", "出现空值");
                }
            }

        } else if (!ret.equals("Error")){
            GetEqual = false;

            //还原显示框大小
            activityMainBinding.ScanfEditText.setTextSize(40);
            activityMainBinding.PrintfText.setTextSize(30);

            //清空储存的内容
            SumNumber.clear();
            Number.setLength(0);
            //还原字体大小
            SIzeOfText = 40;

            SumNumber.add(ret);
            SumNumber.add(str);

            ret = "";
        }
    }

    //使得按下数字后动态计算结果
    private void DynamicCalculation() {
        if(!SumNumber.isEmpty() && SumNumber.size() > 0){
            //将number的数据放入Sumnumber
            if (!Number.equals("") && Number != null) {
                //保存数据
                try {
                    SumNumber.add(String.valueOf(Number));
                } catch (NumberFormatException e) {
                    Log.d("Number", "出现空值");
                }

            }

            //计算当前结果
            ReversePolish reversePolish = new ReversePolish(SumNumber);
            ret = reversePolish.EvaluatePostfixExpressions();

            //删去暂时存放的数据
            SumNumber.remove(SumNumber.size() - 1);
        }
    }
}


2.2 中缀表达式转后缀表达式,使用逆波兰计算

package com.example.computermoblie;

import android.content.Intent;
import android.util.Log;
import android.view.View;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Stack;

public class ReversePolish {
    public List<String> SumNumber;


    Stack<BigDecimal> SymbolStack = new Stack<>();

    //表示没有计算错误的情况
    private boolean Error = false;

    public static final int LeftBrack = 0;   //左括号优先级
    public static final int AandS = 1;   //加减法
    public static final int MandD = 2;   //乘除
    public static final int RightBrack = 3;   //右括号优先级

    //中缀转后缀
    public Queue<String> InfixToSuffix() {
        Queue<String> queue = new ArrayDeque<>();
        Stack<String> swapStack = new Stack<>();

        for (int i = 0; i < SumNumber.size(); i++) {
            String isStr = SumNumber.get(i);

            if (!IsSymbol(isStr)) {
                queue.add(isStr); // 将数字直接添加到输出队列中
            } else {
                if (swapStack.isEmpty() || isStr.equals("(")) {
                    swapStack.push(isStr);
                } else if (isStr.equals(")")) {
                    if(!swapStack.isEmpty()){
                        while (!swapStack.peek().equals("(")) {
                            queue.add(swapStack.pop());
                        }
                        swapStack.pop(); // 弹出 "("
                    }
                } else {
                    while (!swapStack.isEmpty() && JudgmentPriority(swapStack.peek(), isStr)) {
                        queue.add(swapStack.pop());
                    }
                    swapStack.push(isStr);
                }
            }
        }

        while (!swapStack.isEmpty()) {
            queue.add(swapStack.pop());
        }

        return queue;
    }

    public String EvaluatePostfixExpressions() {
        Error = false;  // 表示运算未发现错误
        BigDecimal ret = null; // 表示最后的运算结果
        Queue<String> queue = InfixToSuffix();  // 获取后缀表达式

        Log.d("WQWQ",queue.toString());

        while (!queue.isEmpty()) {
            String str = queue.remove();

            if (!IsSymbol(str)) {
                //保存数据
                try {
                    BigDecimal number = new BigDecimal(str);
                    SymbolStack.push(number);
                } catch (NumberFormatException e) {
                    Log.d("Number","出现空值");
                }
            } else {
                if (SymbolStack.size() < 2) {
                    Error = true; // 栈中元素不足2个,运算错误
                    break;
                }

                BigDecimal op2 = SymbolStack.pop();
                BigDecimal op1 = SymbolStack.pop();
                BigDecimal result = null;

                switch (str) {
                    case "+":
                        result = op1.add(op2);
                        break;
                    case "-":
                        result = op1.subtract(op2);
                        break;
                    case "×":
                        result = op1.multiply(op2);
                        break;
                    case "÷":
                        if (op2.compareTo(BigDecimal.ZERO) == 0) {
                            Error = true; // 除数为零,运算错误
                            break;
                        }
                        result = op1.divide(op2, 3, RoundingMode.HALF_UP);
                        break;
                    default:
                        Error = true; // 非法的运算符,运算错误
                        break;
                }

                if (Error) {
                    break;
                } else {
                    SymbolStack.push(result);
                }
            }
        }

        if (Error) {
            return "Error"; // 出现错误后直接返回错误信息
        } else {
            if (!SymbolStack.isEmpty()) {
                ret = SymbolStack.pop();
            }
            // 使用toEngineeringString()方法将结果输出为工程计数法
            return ret.toEngineeringString();
        }
    }

    public ReversePolish(List<String> sumNumber) {
        SumNumber = sumNumber;
    }

    //判断是否为符号
    public boolean IsSymbol(String str) {
        boolean isSymbole = false;
        if (str.equals("+")) {
            isSymbole = true;
        } else if (str.equals("-")) {
            isSymbole = true;
        } else if (str.equals("×")) {
            isSymbole = true;
        } else if (str.equals("÷")) {
            isSymbole = true;
        } else if (str.equals("(")) {
            isSymbole = true;
        } else if (str.equals(")")) {
            isSymbole = true;
        }

        return isSymbole;
    }

    //判断优先级
    public boolean JudgmentPriority(String PreantStr, String SunStr) {
        //默认PreantStr优先级小于SunStr
        boolean value = false;

        if (SymbolValue(PreantStr) >= SymbolValue(SunStr)) {
            value = true;
        }

        return value;
    }

    //判断属于什么符号
    public int SymbolValue(String str) {
        int Value = LeftBrack;

        if (str.equals("+")) {
            Value = AandS;
        } else if (str.equals("-")) {
            Value = AandS;
        } else if (str.equals("×")) {
            Value = MandD;
        } else if (str.equals("÷")) {
            Value = MandD;
        } else if (str.equals("(")) {
            Value = LeftBrack;
        } else if (str.equals(")")) {
            Value = RightBrack;
        }
        return Value;
    }

    public List<String> getSumNumber() {
        return SumNumber;
    }
}

主要代码如上,此外笔者代码存在一个空指针异常(NullPointerException)的问题,问题出在SumNumber如果多次使用删除键反复输入数据在删除这种测试操作会导致空指针异常,使得操作SumNumber的代码逻辑访问到空指针。这个问题笔者解决了很久都没找到问题所在,如有找到问题所在烦请告知笔者,不胜感激。具体异常信息如下:

根据日志信息,异常的原因是在某个地方尝试调用一个对象的toString()方法,但该对象为空(null),因此无法执行该方法。

根据提供的堆栈跟踪信息,可以看出空指针异常(NullPointerException)在以下方法中被抛出:

  1. com.example.computermoblie.ReversePolish.InfixToSuffix(ReversePolish.java:45)

    制作一个简易的计算器app,Android,android,开发语言,java,xml

  2. com.example.computermoblie.ReversePolish.EvaluatePostfixExpressions(ReversePolish.java:69)

制作一个简易的计算器app,Android,android,开发语言,java,xml

  1. com.example.computermoblie.MainActivity.onClick(MainActivity.java:189)

制作一个简易的计算器app,Android,android,开发语言,java,xml

  1. com.example.computermoblie.MainActivity.DynamicCalculation(MainActivity.java:872)

制作一个简易的计算器app,Android,android,开发语言,java,xml文章来源地址https://www.toymoban.com/news/detail-606998.html

到了这里,关于制作一个简易的计算器app的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android Studio:一个简单的计算器app的实现过程<初级>

    📌Android Studio 专栏正在持续更新中,案例的原理图解析、各种模块分析💖这里都有哦,同时也欢迎大家订阅专栏,获取更多详细信息哦✊✊✊ ✨个人主页:零小唬的博客主页 🥂欢迎大家 👍点赞 📨评论 🔔收藏 ✨作者简介:20级计算机专业学生一枚,来自宁夏,可能会去

    2024年02月01日
    浏览(106)
  • Android Studio简易计算器

    目录 第一步,创建新项目 第二步,设计UI 第三步,实现计算逻辑 第四步,测试应用程序 随着移动互联网的普及,手机应用程序已经成为人们生活中不可或缺的一部分。计算器是一类被广泛使用的应用程序之一,因此学习如何开发一款简易的计算器应用程序是学习Android Stu

    2024年02月08日
    浏览(36)
  • 【Android Studio】简易计算器

    简易计算器要求: 1,操作简单,易于掌握,界面简单。 2.方便进行加,减,乘,除等操作。数字保留小数点后两位。 3.包含小数点运算和输入回退功能。 4.能够进行多次叠加运算。 5.系统能够进行多次叠加运算。 6.系统可以稳定运行。 功能图如下: 逻辑流程图如下: 项目建

    2024年02月08日
    浏览(44)
  • 【Android】控件与布局入门 - 简易计算器

    目录 1. 基础开发环境 2. 计算器的布局和相关按钮 3. 计算器的主要运算逻辑 4. APK 文件 5. 项目源码 JDK:JDK17 Android Studio:Android Studio Giraffe | 2022.3.1 Android SDK:Android API 34 Gradle: gradle-8.0-bin.zip 使用 LinearLayout 和 GridLayout 实现计算器的交互前端。 layout 文件如下 相关 values 如下:

    2024年02月14日
    浏览(51)
  • Android开发:kotlin语言实现简易计算器

    输入两个数字,可选加减乘除操作符,并计算显示对应结果 随系统切换语言 可对结果进行四舍五入操作 界面布局:activity_main.xml文件代码 字符定义:string.xml文件代码 逻辑实现:MainActivity.kt 文件代码 方法一(偷懒): 复制文件到对应位置 方法二: 1. 绘制界面 2. 编写逻辑

    2023年04月08日
    浏览(48)
  • 学会使用Android Studio网格布局制作计算器界面

    1.1GridLayout布局使用虚细线将布局划分为行、列和单元格,也支持一个控件在行、列上都有交错排列。 1.2可以自己设置布局中组件的排列方式 1.3可以自定义网格布局有多少行、多少列 1.4可以直接设置组件位于某行某列 1.5可以设置组件横跨几行或者几列 基于-  Empty Activity 模板

    2024年02月08日
    浏览(46)
  • JAVA制作的简易计算器——傻瓜计算器

    用JAVA编写的傻瓜计算器 作用: 1.可以实现加法、减法、乘法、除法简单运算且是单一运算,不可混合使用。 2.CE为清除键 3.没有小数点O(∩_∩)O 思路: 创建JFrame窗口,设置标题,创建JButton,创建文本框JTextField用作显示。 先定义各种按钮类型,用作成员。定义窗口方法对窗口

    2024年02月11日
    浏览(45)
  • C# 制作简易计算器

    前言:环境是vs 2022 1、打开vs2022后,右边导航栏选择创建新项目。  2、选择Windows窗体应用(.net  Framework)  3、进入配置新项目界面(项目名称和位置可自行修改)点击创建  4、窗体From1即为我们要要编辑的位置  5、在窗体中添加对应的工具 6、并在对应的属性窗口为其修改

    2024年02月08日
    浏览(50)
  • Android Studio实现简易计算器(带横竖屏,深色浅色模式,更该按钮颜色,selector,style的使用)

    目录 前言 运行结果: 运行截屏(p50e)  apk文件 源码文件  项目结构 总览 MainActivity.java drawable 更改图标的方法: blackbutton.xml bluebuttons.xml greybutton.xml orangebuttons.xml whitebutton.xml layout 布局文件  竖屏: 横屏: values         colors.xml strings.xml styles 浅色模式 深色模式 themes.xml

    2024年02月06日
    浏览(44)
  • MFC基于对话框——仿照Windows计算器制作C++简易计算器

    目录 一、界面设计 二、设置成员变量 三、初始化成员变量  四、初始化对话框 ​五、添加控件代码 1.各个数字的代码(0~9) 2.清除功能的代码 3.退格功能的代码 4.加减乘除功能的代码 5.小数点功能的代码 6.正负号功能的代码 7.等于功能的代码 六、源码领取方式 制作好之后

    2024年02月05日
    浏览(70)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包