Android калкулатор: бутон за десетичен знак

Аз съм нов в разработването на Android и в момента се уча да проектирам за основно приложение за калкулатор. Вече сам проектирах оформлението, но извадих кодове за основна дейност от различни уебсайтове за операциите от 0 до 9, +, -, *, / и след включването те работят добре.

Въпреки това искам да модифицирам допълнително MainActivity с функцията за десетична запетая. Докато цялото число може да бъде показано правилно на екрана, използвайки "текущо = текущо * 10 + число", например 53 = 5*10+3;

Мисля да приложа същия подход за десетична запетая с функция за цикъл, като идеята е следната: 1. текущо = текущо + оставащо, ако се натисне бутон с точка 2. създайте цяло число i, i се увеличава с 1, след като се щракне върху произволен цифров бутон 3 , така че когато напр. вход 5.3, i =1, той ще = 5 + 3/(10^i) = 5.3 4. 5.3 цикъл до тук, тогава когато напр. въведете като 5.39, сега i=2, ще бъде = 5.3 + 9/(10^i) = 5.39

ВЪПРОС >> *И все пак...наистина...аз съм толкова свеж, че не знам как да проектирам кодирането за десетичния бутон, има ли някой, който да предложи кода? * първо игнорирайте следните добавки, където трябва да бъдат открити грешки (като изтриване на втората точка, ако точката е въведена два пъти или повече, добавяне на 0 пред ., ако да кажем, че е въведено .5)

Идентификаторът на бутона е както следва и веднъж щракнат за препратка към DecimalClickEvent Button b_decimal = (Button) findViewById(R.id.decimal); b_decimal.setOnClickListener(ново DecimalClickEvent(???));}

Много много благодаря предварително!! Кодовете са приложени по-долу за справка и вашите коментари:

==========================MainActivity.java======================= ================

package com.trial.newcalculator;

import java.io.Serializable;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

@SuppressLint("ParserError")
public class MainActivity extends Activity {
    State s;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);
        s = new State();

        int[] opNumbers = new int[] { 
                R.id.zero,
                R.id.one,
                R.id.two,
                R.id.three,
                R.id.four,
                R.id.five,
                R.id.six,
                R.id.seven,
                R.id.eight,
                R.id.nine,     
        };

        final TextView textView = (TextView) findViewById(R.id.ansEditText);
        for (int i = 0; i < 10;i++){
            final Button button = (Button) findViewById(opNumbers[i]);        
            button.setOnClickListener(new NumberClickEvent(textView,s,i));          
        }

      int[] opButtons = new int[] { R.id.add, R.id.subtract, R.id.multiply, R.id.divide };
      State.Operation[] states = new State.Operation[] {
                State.Operation.PLUS, 
                State.Operation.MINUS,
                State.Operation.MULTIPLY, 
                State.Operation.DIVIDE};

        for(int i = 0; i < opButtons.length;i++){
        Button b_op = (Button) findViewById(opButtons[i]);
        b_op.setOnClickListener(new OperationClickEvent(textView, s, states[i]));
        }

// Memory functions
        int[] memButtons = new int[] { R.id.MC, R.id.MR, R.id.Mdeduct, R.id.Mplus};
        State.Operation[] mstates = new State.Operation[] {
                State.Operation.MEMORYCLEAR, 
                State.Operation.MEMORYCALL,
                State.Operation.MEMORYMINUS, 
                State.Operation.MEMORYPLUS};

        for(int i = 0; i < memButtons.length;i++){
        Button b_mem = (Button) findViewById(memButtons[i]);
        b_mem.setOnClickListener(new OperationClickEvent(textView, s, states[i]));
        }
//  Memory functions    

//decimal
//      Button b_decimal = (Button) findViewById(R.id.decimal);
//      b_decimal.setOnClickListener(new DecimalClickEvent(textView, s, "."));   
//decimal

        Button b_eq = (Button) findViewById(R.id.equal);
        b_eq.setOnClickListener(new EqualClickEvent(textView, s));

        Button b_op = (Button) findViewById(R.id.ac);
        b_op.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                s.clear();
                textView.setText(s.getDisplay());
            }
        });               
    }      
@Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        savedInstanceState.putSerializable("STATE", s);
    }

    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
        Serializable serializable = savedInstanceState.getSerializable("STATE");
        if(serializable!= null){
            s = (State) serializable;
        }
    }

    public void onPause(){
         super.onPause();
    }

}

===============================State.java================= ===================

package com.trial.newcalculator;

import java.io.Serializable;
import android.text.Editable;
import android.widget.TextView;

public class State implements Serializable {
    private static final long serialVersionUID = -1231231231231233L;
    public TextView output;
    public enum Operation {     
        PLUS,       
        MINUS,      
        MULTIPLY,       
        DIVIDE,     
        MEMORYPLUS,
        MEMORYMINUS,
        MEMORYCALL,
        MEMORYCLEAR,
    }   
    public enum IOState{        
        INPUTTING,      
        DISPLAY_RESULT, 
    }   
    private Double accu = null; 
    private double current = 0; 
    private double memory = 0;
    private Operation currentOp = null; 
    private IOState currentState = IOState.INPUTTING;   
    public Operation getCurrentOp() {       
        return currentOp;   
    }   
    public void setCurrentOp(Operation currentOp) {     
        if (currentState == IOState.INPUTTING){         
            if (accu != null && this.currentOp != null ){calculateResult(); 
            }
            else{accu = Double.valueOf(current);current = 0;
            }
        }
        this.currentOp = currentOp;     
        if (currentState == IOState.INPUTTING){
            currentState = IOState.DISPLAY_RESULT;
        }   
    }   
    private void calculateResult() {
        double res = accu.doubleValue();
        switch (currentOp) {
            case PLUS:
                res += current;
                break;
            case MINUS:
                res -= current;
                break;
            case MULTIPLY:
                res *= current;
                break;
            case DIVIDE:
                res /= current;
                break;
            case MEMORYPLUS:
                memory += current;
                break;
            case MEMORYMINUS:
                memory -= current;
                break;
            case MEMORYCLEAR:
                memory = 0;
                break;
            case MEMORYCALL:
                current = memory;
                break;
        }
        accu = Double.valueOf(res);
        current = 0;
    }
    public void number(int number) {
        if (currentState == IOState.INPUTTING){
            current = current *10 + number;
        }
        else if(currentState == IOState.DISPLAY_RESULT){
            currentState = IOState.INPUTTING;
            current = number;
        }
    }
    public String getDisplay() {
        String res;
        Double d = getCurrentDisplayValue();
        double doubleValue = d.doubleValue();
        int intVal = (int)doubleValue;
        if (intVal == doubleValue){
            res = Integer.toString(intVal);
            }
        else{
            res = d.toString();
            }
        return res;
    }
    private Double getCurrentDisplayValue() {
        Double d = accu;
        if (currentState == IOState.INPUTTING){
            d = Double.valueOf(current);
        }
        return d;
    }
    public void clear() {
        accu = null;
        currentState = IOState.INPUTTING;
        currentOp = null;
        current = 0;
    }

    public void equal() {
        if (accu == null || currentOp == null){
            return;
        }
        calculateResult();
        currentState = IOState.DISPLAY_RESULT;
        currentOp = null;
        current = getCurrentDisplayValue(); 
        }
}

=====================OperationClickEvent.java============================ ====

package com.trial.newcalculator;

import com.trial.newcalculator.State.Operation;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

final class OperationClickEvent implements OnClickListener {
    private State s;
    private TextView textView;
    private Operation op;


    public OperationClickEvent(TextView textView, State s, State.Operation op) {
        super();
        this.op = op;
        this.s = s;
        this.textView = textView;
    }


    public void onClick(View v) {
        s.setCurrentOp(op);
        textView.setText(s.getDisplay());
    }
}

=================EqualClickEvent.java================================ =========

package com.trial.newcalculator;

import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

final class EqualClickEvent implements OnClickListener {
    private State s;
    private TextView textView;


    public EqualClickEvent(TextView textView, State s) {
        super();
        this.s = s;
        this.textView = textView;
    }


    public void onClick(View v) {
        s.equal();
        textView.setText(s.getDisplay());
    }
}

=======================NumberClickEvent.java=========================== =========

package com.trial.newcalculator;

import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

final class NumberClickEvent implements OnClickListener {
    private int number;
    private State s;
    private TextView textView;


    public NumberClickEvent(TextView textView, State s, int number) {
        super();
        this.number = number;
        this.s = s;
        this.textView = textView;
    }


    public void onClick(View v) {
        s.number(number);
        textView.setText(s.getDisplay());
    }
}

person pearmak    schedule 13.08.2012    source източник


Отговори (2)


Вместо да създавате нови класове за събитие с отрицателно щракване и doublezeroclickevent, предлагам ви да получите техните идентификатори и да извършите правилната функционалност, когато се щракне върху конкретния бутон.

person G_S    schedule 13.08.2012
comment
да да...благодаря за съвета ви...съжалявам, че съм начинаещ и това е просто някакво лично предпочитание да разделяте нещата в отделни класове, за да направите програмата по-кратка и по-лесна за дебют...да...но наистина не може да работи разберете как да проектирате класове за 1) десетична 2) +/- 3) двойна нула - person pearmak; 13.08.2012
comment
За двойна нула опитайте да умножите конкретната стойност със 100 и я покажете, когато се щракне върху конкретната двойна нула - person G_S; 14.08.2012
comment
И стигаме до десетичната.. Когато потребителят щракне върху десетичния бутон, добавете . към числото (мислейки, че е низ) и отново го анализирайте във Float. Опитай. - person G_S; 14.08.2012
comment
всъщност как да анализирам? сега е, че когато се натискат бутони с цифри, това става чрез целочислената променлива, наречена number, и се добавя към двойната променлива current по начин, който current=current*10+number би ли било практично да се направи цикъл fcn, така че: 1. current = текущо + оставащо, ако се натисне бутон с точка 2. създайте цяло число i, i се увеличава с 1 след щракване върху който и да е цифров бутон 3. така че когато напр. вход 5.3, i =1, той ще = 5 + 3/(10^i) = 5.3 4. 5.3 цикъл до тук, тогава когато напр. въведете като 5.39, сега i=2, ще бъде = 5.3 + 9/(10^i) = 5.39, ако използвате анализ, трябва да преработите всички? - person pearmak; 14.08.2012
comment
Мисля, че имаме нещо като Float.parseFloat(string value); След като го проверите - person G_S; 14.08.2012
comment
Благодаря! тези дни преработих кодирането така, че да внедря метода като float.parseFloat(низова стойност). Той е много по-прост без намеса на математика и определено е по-добър метод. - person pearmak; 23.08.2012

Всеки OnClickListener може да бъде анонимен клас по подразбиране, който ще бъде задействан само от един бутон. Така че няма нужда да ги наричате „NegativeClickEvent“, „DoublezeroClickEvent“ и т.н.

Можете да запазите булева променлива, ако "." е натиснат и приемете друг само ако не. Ако искате използваем калкулатор, имате нужда и от бутон "backspace". Така че имайте предвид, че точката може да бъде изтрита. (трябва да следите разположението му).

За водещата 0 можете да използвате просто „ако първо е била натисната точката, вмъкнете 0.“.

Има много начини да приложите това, което искате, но за да бъде просто, просто се справете със случаите, които трябва да обработите.

Други начини за прилагане на това може да включват Double.parseDouble(s) с catch (NumberFormatException e) на всеки натиснат клавиш или използване на двоен като буфер и използване на бутоните за директно извършване на математически операции върху него (като умножение по 10 и добавяне на новата цифра при всяко натискане на бутон) - това ще гарантира валидност на входа без необходимост от анализ на низ, но е по-сложно за изпълнение.

person Amir Uval    schedule 13.08.2012
comment
благодаря много за съвета!! да, мисля да добавя функция за памет, функция за връщане назад и функция +/- също. - person pearmak; 13.08.2012
comment
кодът по-горе използва Текущо = текущо *10 + число, това може би за това, което казвате по-горе... но просто искам да знам повече, би ли било работа за въвеждане с десетични знаци по-късно? тогава ще се промени ли, за да пише като например, ако няма точка, current = current * 10 + num, ако съдържа точка, current = current + num /10? (но не знам други знаци след десетичната запетая, които да бъдат въведени..) благодаря много за съвета ви!! - person pearmak; 13.08.2012
comment
ще трябва да следите десетичния знак, за да добавите current/Math.pow(10,place). Има повече сложности, ако поддържате backspace. Друг подход е да се използва десетична запетая само за изобразяване и да се приложи след завършване на редакцията, а дотогава да се използва цяло число + променлива за десетично поставяне. - person Amir Uval; 14.08.2012
comment
Обърнете внимание на второто ми предложение да използвате String (всъщност StringBuilder), за да редактирате числото и да го валидирате на всяка стъпка с помощта на Double.parseDouble(s), като приемате всеки нов символ само ако не е хвърлено NumberFormatException. Много е лесно за изпълнение, без да се намесва математика. - person Amir Uval; 14.08.2012