Android calculator

Posted by skeppens on Mon, 10 Jan 2022 01:57:00 +0100

1, Experimental purpose

Practice mastering the interface layout, event programming and other basic programming technologies of Android Software development, and design and make an Android calculator software.

2, Experimental content

The calculator function and interface realized can be designed by each student in the experimental development. The following functions and software circles are for reference:
The basic functions of a calculator shall include input data, addition, subtraction, multiplication and division, floating-point operation, sine and cosine operation, clearing results and deleting one bit of data.
(1) Numbers are input in the form of characters. When you need to read data, you can directly call getText() function.
(2) For the binocular operator, when a click is detected, the data num1 in the input box is obtained, the input box is empty, and a flag op is set to indicate which operation it is. For division operation, you need to judge whether the divisor is zero and remind.
(3) For monocular operators, when a click is detected, a flag or is set to indicate which operation it is. (4) When emptying, you need to empty the input box. When clearing one bit of data, judge whether there is only one data in the input box. If so, clear it directly. If not, set the first n-1 bit in the input box.
(5) When you click the equals symbol, you will get the data num2 in the input box. According to the flag bit set above, you can judge whether you click a monocular operator or a binocular operator. If it is a monocular operator, you will perform a monocular operation on num2. If it's a binocular operation, num2 doesn't change. Then perform the Result operation.

3, Experimental requirements

(1) Each student independently designs software functions and completes software development and testing.
(2) Each student completes the experiment report independently (according to the template) and submits it to the online classroom

The calculator is divided into two modes, including standard mode and scientific calculation
Because there are many source codes, only the core scientific computing part is released
The code given below mainly involves event triggering and global information transmission
Description: ScientificCalculator java

package com.example.luozenglin.service;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.example.luozenglin.calculator.MainActivity;
import com.example.luozenglin.calculator.R;
import com.example.luozenglin.common.InputItem;
public class ScientificCalculator extends StandardCalculator {
    protected Button antiBtn;
    protected Button perCent;
    protected Button sinBtn;
    protected Button cosBtn;
    protected Button tanBtn;
    protected Button powerBtn;
    protected Button lgBtn;
    protected Button lnBtn;
    protected Button leftBraBtn;
    protected Button rightBraBtn;
    protected Button squareRootBtn;
    protected Button factorialBtn;
    protected Button reciprocalBtn;
    protected Button pIBtn;
    protected Button eBtn;
    public ScientificCalculator(Activity activity){
        super(activity);
    }
    @Override
    protected void init() {
        super.init();
        antiBtn = (Button) activity.findViewById(R.id.anti_btn);
        sinBtn = (Button) activity.findViewById(R.id.sin_btn);
        cosBtn  = (Button) activity.findViewById(R.id.cos_btn);
        tanBtn = (Button) activity.findViewById(R.id.tan_btn);
        powerBtn = (Button) activity.findViewById(R.id.power_btn);
        lgBtn = (Button) activity.findViewById(R.id.log_btn);
        lnBtn = (Button) activity.findViewById(R.id.ln_btn);
        leftBraBtn = (Button) activity.findViewById(R.id.leftBracket_btn);
        rightBraBtn = (Button) activity.findViewById(R.id.rightBracket_btn);
        squareRootBtn = (Button) activity.findViewById(R.id.squareRoot_btn);
        factorialBtn = (Button) activity.findViewById(R.id.factorial_btn);
        reciprocalBtn = (Button) activity.findViewById(R.id.reciprocal_btn);
        pIBtn = (Button) activity.findViewById(R.id.PI_btn);
        eBtn = (Button) activity.findViewById(R.id.e_btn);
        perCent = (Button) activity.findViewById(R.id.perCent_btn);
        map.put(sinBtn,activity.getString(R.string.sin));
        map.put(cosBtn,activity.getString(R.string.cos));
        map.put(tanBtn,activity.getString(R.string.tan));
        map.put(powerBtn,activity.getString(R.string.power));
        map.put(perCent, "%");
        map.put(lgBtn,activity.getString(R.string.log));
        map.put(lnBtn,activity.getString(R.string.ln));
        map.put(leftBraBtn,activity.getString(R.string.leftBra));
        map.put(rightBraBtn,activity.getString(R.string.rightBra));
        map.put(squareRootBtn,activity.getString(R.string.squareRoot));
        map.put(factorialBtn,activity.getString(R.string.factorial));
        map.put(reciprocalBtn,activity.getString(R.string.reciprocal));
        map.put(pIBtn,activity.getString(R.string.PI));
        map.put(eBtn,"e");
    }
    @Override
    protected void setOnClickListener() {
        super.setOnClickListener();
        powerBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                inputOpe(v);
            }
        });
        perCent.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                inputOpeOpe(v);
            }
        });
        antiBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                transTrigon();
            }
        });
        sinBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                inputNumOpe(v);
            }
        });
        cosBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                inputNumOpe(v);
            }
        });
        tanBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                inputNumOpe(v);
            }
        });
        lgBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                inputNumOpe(v);
            }
        });
        lnBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                inputNumOpe(v);
            }
        });
        squareRootBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                inputNumOpe(v);
            }
        });
        leftBraBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                inputLeftBra();
            }
        });
        rightBraBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                inputRightBra();
            }
        });
        factorialBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                inputOpeOpe(v);
            }
        });
        reciprocalBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                inputOpeOpe(v);
            }
        });
        pIBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                inputOpeNum(v);
            }
        });
        eBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                inputOpeNum(v);
            }
        });
    }
    @Override
    protected void transform() {
        Intent intent = new Intent(activity, MainActivity.class);
        activity.startActivity(intent);
    }
    protected void transTrigon(){
        if(antiBtn.getText().equals(activity.getString(R.string.radian))){
            antiBtn.setText(activity.getString(R.string.deg));
        }else if(antiBtn.getText().equals(activity.getString(R.string.deg))){
            antiBtn.setText(activity.getString(R.string.radian));
        }
    }
    protected void inputTrigonometricFunction(View view){
    }
    protected void inputNumOpe(View view){
        if( currentStatus == CurrentStatus.END){
            initEndStatus();
        }
        if(isInitInputList()){
            subInputListAndInputTV();
        } else if(getLastInputItem().getType()== InputItem.TYPE.NUM ||
                getLastInputItem().getType()== InputItem.TYPE.RIGHT_BRACKET){
            inputOpe(mulBtn);
        }
        inputList.add(new InputItem(map.get(view), InputItem.TYPE.NUM_OPE));
        addTV(view);
        inputLeftBra();
        Log.i(activity.getClass().getSimpleName(),"add ope: "+map.get(view)+
                "\ninputList: "+getInputListValues());
    }
    protected void inputOpeOpe(View view) {
        if (getLastInputItem().getType()!= InputItem.TYPE.NUM                      //OPT_OPT must be preceded by a number or a closing parenthesis
                && getLastInputItem().getType()!= InputItem.TYPE.RIGHT_BRACKET) {
            Log.i(activity.getClass().getSimpleName(),"Last input is "+
                    getLastInputItem().getValue()+", can not add "+map.get(view));
            return;
        }
        inputList.add(new InputItem(map.get(view), InputItem.TYPE.OPE_OPE));
        addTV(view);
        Log.i(activity.getClass().getSimpleName(),"inputList:  "+getInputListValues());
    }
    protected void inputOpeNum(View view){
        if( currentStatus == CurrentStatus.END){
            initEndStatus();
        }
        if(isInitInputList()){
            subInputListAndInputTV();
        }else if(getLastInputItem().getType()== InputItem.TYPE.NUM ||
                getLastInputItem().getType()== InputItem.TYPE.RIGHT_BRACKET){
            inputOpe(mulBtn);
        }
        inputList.add(new InputItem(map.get(view), InputItem.TYPE.OPE_NUM));
        addTV(view);
        Log.i(activity.getClass().getSimpleName(),"add ope: "+map.get(view)+
                "\ninputList: "+getInputListValues());
    }
    protected void inputLeftBra(){
        if( currentStatus == CurrentStatus.END){
            initEndStatus();
        }
        if(isInitInputList()){
            subInputListAndInputTV();
        }else if(getLastInputItem().getType()!= InputItem.TYPE.OPE && getLastInputItem().getType()!= InputItem.TYPE.NUM_OPE
                && getLastInputItem().getType()!= InputItem.TYPE.LEFT_BRACKET){
            inputOpe(mulBtn);
        }
        inputList.add(new InputItem(map.get(leftBraBtn), InputItem.TYPE.LEFT_BRACKET));
        addTV(leftBraBtn);
        Log.i(activity.getClass().getSimpleName(),"add ope: "+map.get(leftBraBtn)+
                "\ninputList: "+getInputListValues());
    }
    protected void inputRightBra(){
        if(getLastInputItem().getType()== InputItem.TYPE.OPE){
            subInputListAndInputTV();
        }
        inputList.add(new InputItem(map.get(rightBraBtn), InputItem.TYPE.RIGHT_BRACKET));
        addTV(rightBraBtn);
        Log.i(activity.getClass().getSimpleName(),"add ope: "+map.get(rightBraBtn)+
                "\ninputList: "+getInputListValues());
    }
}

The following screenshot shows the layout of the calculator, divided into standard and advanced


Android Studio pit

Error:Protocol family unavailable this error means that the problem of firewall is not true in many places. reference resources http://bbs.csdn.net/topics/391951751?page=1 Add a new variable to the environment variable_ JAVA_OPTIONS has a variable value of - DJava net. Preferipv4stack = true, and then restart Android studio
Error running app: Instant Run requires 'Tools | Android | Enable ADB integration' to be enabled. Solution: menu bar, tools - > adnroid - > enable ADB integration
Error:(1, 0) Cause: com/android/build/gradle/LibraryPlugin : Unsupported major.minor version 52.0 the reason for this error is in the project build The gradle tool configuration in the gradle file uses gradle: it classpath 'com Android. tools. build:gradle:’
Replace with a fixed version of gradle. classpath “com.android.tools.build:gradle:2.1.0”
Android Studio error: illegal character: '\ UFF' solution | error: class, interface or enum is required. Solution: manually convert the UTF-8+BOM encoded file to an ordinary UTF-8 file. Open with EdItPlus java files: document text editing convert text encoding select UTF-8 encoding
The following problems occurred when importing the project into AS: error: execution failed for task: app: transformresourcewithmergejavaresfordebug 'com android. Bui solution: in build Add the following code to grade:
android{
packagingOptions {
exclude 'META-INF/DEPENDENCIES.txt'exclude
'META-INF/NOTICE'exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/LICENSE'exclude 'META-INF/LICENSE.txt'}}

experience

Sort out some commonly used tool classes or business process codes and add them to your own code base. Such as encryption and decryption, taking pictures, cutting pictures, obtaining the path of all pictures in the system, custom controls or animation, and other commonly used tools. Archiving helps to improve development efficiency and can be easily introduced and used when encountering new projects. If you want to better maintain your code base, you can open source this private code base with detailed documents. In this way, more developers can be attracted to use these codes, and corresponding bug feedback can be obtained, so as to locate and fix problems and enhance the stability of the warehouse code.

Four startup modes of Activity:

• standard: standard mode, which generates a new Activity instance in the Activity stack every time. Usually the activities we use are standard patterns.
• singleTop: stack top reuse. If the Activity instance already has a stack top, no new instance will be created in the Activity stack. A common scenario is to set the Activity for the notification jump, because you certainly don't want to click the notification to create the same Activity for you when the foreground Activity is already the Activity.
• singleTask: reuse in the stack. If the Activity instance already exists in the current stack, all other Activity instances above the current Activity instance will be removed from the stack. It is common to jump to the main interface.
• singleInstance: single instance mode, create a new task stack, and the activity instance is alone in the activity stack.

Four concepts in Android message mechanism:

• ThreadLocal: the data stored by the current thread can only be fetched from the current thread.
• MessageQueue: message queue with time priority.
• Looper: poll the message queue to see if a new message arrives.
• Handler: a specific place to handle logic.
Process:

  1. Preparations: create a Handler. If it is created in a child thread, you also need to call Looper#prepare(). In the constructor of the Handler, the Looper and MessageQueue will be bound.
  2. Send message: create a message and send it using Handler.
  3. Enter MessageQueue: because the Message queue is bound in the Handler, the Message is naturally put into the Message queue.
  4. Looper polls the message queue: Looper is a dead loop, always observing whether there is any new message coming, then removing the bound Handler from Message, and finally calling the processing logic in Handler, all of which happen in the thread of the Looper loop, which is also the reason why Handler can specify the thread processing tasks.

Related resources

Dependent libraries and SDK s

Required Library:
Gradle retrorambda -- lambda expression plug-in for Android
fresco -- Android's best picture loading Library
Material dialogs - Material Dialog downward compatibility Library
Material Ripple -- Ripple downward compatibility Library
fastjson -- fastest JSON parsing
Button knife -- View annotation library and supporting plug-in Android button knife zelezny
ActiveAndroid - database annotation library.
RxAndroid - Rx function responsive programming Chinese document
Retro fit, okhttp, sqlbrite, okio - there are so many boutiques in Square
compile ‘com.android.support:design:23.0.1 '- Google Material Design control library
Here are some libraries written by Amway. If you have any suggestions, welcome to communicate:
Utils - a collection of Android gadgets
RollViewPager -- a convenient ViewPager for automatic rotation
EasyRecyclerView - a comprehensive RecyclerView that supports pull-down, pull-up, refresh and other functions
SwipeBackHelper - Activity slides to close the support library, which can achieve the wechat effect
I've tried a lot. These are commonly used now.
Rongyun - instant messaging
Youmeng - data statistics, push, feedback, automatic update, third-party sharing and login, community
Seven cows - cloud storage
Mob - SMS verification
Bmob - do not ask for people backstage

See the resources I sent for the complete code

Topics: Java Android Android Studio