Android-калькулятор: кнопка для десятичной точки

Я новичок в разработке для Android и в настоящее время изучаю дизайн для базового приложения-калькулятора. Я уже сам разработал макет, но получил коды основной активности с разных веб-сайтов для операций от 0 до 9, +, -, *, /, и после включения они работают нормально.

Однако я хочу дополнительно изменить MainActivity с помощью функции десятичной точки. В то время как целое число можно правильно отобразить на экране, используя «текущий = текущий * 10 + число», например, 53 = 5*10+3;

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

ВОПРОС >> *Пока... правда... Я настолько свеж, что не знаю, как разработать кодировку для десятичной кнопки, кто-нибудь может предложить код? * сначала игнорируйте следующие надстройки, в которых должны быть обнаружены ошибки (например, удалите вторую точку, если точка вводится дважды или более, добавляя 0 перед ., если, скажем, вводится .5)

Идентификатор кнопки выглядит следующим образом, и после нажатия он ссылается на кнопку DecimalClickEvent 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 и добавляется к переменной double current таким образом, что current=current*10+number было бы практично сделать цикл fcn таким, что: 1. current = текущий + оставшийся, если нажата кнопка с точкой 2. создать целое число i, которое увеличивается на 1 после нажатия любой цифровой кнопки 3. так что, например, ввод 5.3, я = 1, это будет = 5 + 3/(10 ^ я) = 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» и т. д.

Вы можете сохранить логическую переменную, если "." был нажат, и принять другой, только если нет. Если вам нужен удобный калькулятор, вам также нужна кнопка «возврат». Так что обратите внимание, что точка может быть удалена. (нужно следить за его размещением).

Для ведущего 0 вы можете использовать простое «если точка была нажата первой, вставьте 0».

Есть много способов реализовать то, что вы хотите, но для простоты просто обрабатывайте случаи, которые вам нужно обработать.

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

person Amir Uval    schedule 13.08.2012
comment
спасибо большое за совет!! да, я думаю о добавлении функции памяти, функции возврата и функции +/-. - person pearmak; 13.08.2012
comment
приведенный выше код использует Current = current * 10 + число, возможно, это связано с тем, что вы сказали выше ... но просто хочу узнать больше, будет ли это работать для ввода с десятичными знаками позже? изменится ли тогда запись, скажем, если нет точки, текущий = текущий * 10 + число, если содержит точку, текущий = текущий + число /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