Criando uma Calculadora - Parte 2


Está é a parte final do nosso tutorial para criar uma calculadora no Android Studio. Se você não viu o primeiro tutorial, leia primeiro para entender onde paramos. "Criando Uma Calculadora - Parte 1".

Lembrando que este tutorial irá criar uma simples calculadora, onde iremos usar basicamente números inteiros, e se o resultado for decimal, ele aproxima para inteiro.

Antes de ir para a parte principal do código, vamos configurar para que o nosso app não rotacione, já que não otimizamos os botões para se encaixar na tela dependendo do aparelho, e sua orientação. Então vamos abrir o AndroidManifest.xml dentro de manifests e dentro da tag da nossa activity, vamos adicionar o modo portrait no screenOrientation. Deve ficar assim:

Agora só como parte estética, vamos trocar a cor da Toolbar, para combinar com o app. Para isso vamos em Tools>Android>Theme Editor, e aqui você pode trocar as cores do tema, as principais para você alterar seriam: colorPrimary, colorPrimaryDark, colorAccent

Pronto, podemos agora ir no main. No ultimo tutorial foi mostrado como vincular todos os elementos do Layout na Classe Java, mas como a calculadora tem muito Button, iria ser mais difícil controlar, pois seria necessário criar um método para cada vez que um for clicado. Então preferimos remover as variáveis para cada botão. 

Deixamos a declaração da tela de resultado na classe, e sua inicialização no onCreate, para que ela possa ser acessada por outras funções, já que o onCreate é do tipo protected e nenhuma variável declarada dentro dele existe em outras funções.
    public class MainActivity extends AppCompatActivity{
        TextView RESULTSCREEN;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            RESULTSCREEN = (TextView) findViewById(R.id.RESULTSCREEN);
        }
    }
Para ainda ter controle do que foi clicado, você precisará na sua classe implementar o View.OnClickListener na nossa classe. No final ficará assim:

    public class MainActivity extends AppCompatActivity implements View.OnClickListener

Ele pedirá para você criar um método onClick, e no final deve ficar assim:

    @Override
    public void onClick(View view) {
        //SEU CODIGO
    }
Pronto, agora temos que configurar para que toda vez que um botão seja clicado, ele chame esta função. Para isso vamos no res/layout/activity_main.xml, selecionar todos os botões, e na área de propriedades temos que marcar em clickable e onClick escolher a função onClick que acabamos de criar. 

Agora podemos voltar para a Classe Java, pois toda vez que um botão for clicado, ele irá chamar a função onClick.

Agora vamos declarar as variáveis que iremos utilizar ao longo do programa. Todas elas fora de funções para poder se utilizada em qualquer função.
    int i = 0;
    int count = 0; //Conta quantos numeros foram adicionados para não passar do limite
    int[] Result;
    int Total = 0;
    static int INVALID = 9999999; //Limite de numeros
Com as variáveis criadas, vamos no onCreate setar para que o vetor de inteiro Result tenha 2 posições, para o intuito dele preencher a primeira posição até que algum operador for clicado, assim preenchendo a segunda, e quando o botão igual for clicado efetuar a operação.
    Result = new int[2];
Vamos precisar saber qual botão foi clicado, e para isso vamos fazer um imenso switch. Podemos apenas por organização fazer dois, onde um terá apenas os operadores, e o outro os números. O de operadores receberá como parâmetro o  view.getId() para que em cada case, seja checado o ID do view. Precisaremos também de uma variável do tipo String chamada operador, que guardará qual operador foi clicado. Então ficará assim:
    String operator;
    @Override
    public void onClick(View view) {
        //Caso os operadores forem clicados
        switch (view.getId()) {
            case R.id.buttonsoma: operator = "soma";    //Soma
                proximoNumero();
                break;
            case R.id.buttonsub: operator = "sub";      //Subtração
                proximoNumero();
                break;
            case R.id.buttonmult: operator = "mult";    //Multiplicação
                proximoNumero();
                break;
            case R.id.buttondiv: operator = "div";      //Divisão
                proximoNumero();
                break;
            case R.id.buttonigual: calcular();          //Calcula
                count = 0;
                break;
            case R.id.buttonLimpar: limpar();           //Limpar tudo
                break;
        }
    }
Agora vamos criar as funções proximoNumero( ) e limpar( ). Deixaremos a calcular para quando fizermos o segundo switch. O proximo número passa a posição do vetor Result, e o limpar faz com que todas as variáveis sendo utilizadas recebam o valor zero.
    //Passa o para a próxima posição do vetor
    private void proximoNumero(){
        count = 0;  //Zera a quantidade de Números
        i = 1;      //Passa para o primeiro numero do vetor
    }
    //Limpar a Tela
    private void limpar(){
        i = 0;          //Passa para o primeiro numero do vetor
        Result[0] = 0;  //Zera os vetores
        Result[1] = 0;
        Total = 0;      //Zera o total
        count = 0;      //Zera a quantidade de Números
    }
Vamos fazer o segundo switch dentro do onClick, mas antes vamos colocar a condição de count não pode ser maior que 7 pois delimitará a quantidade de números que poderão ser digitados pelo usuário. Com isso o switch seguirá as mesmas premissas do de operador, sendo que o count será acrescentado todas as vezes que um case for verdadeiro. é calculado também antes o (Result[i] * 10) para prevenir que um valor sobrescreva o outro.
    //Se for menor que o tamanho máximo da tela
    if(count < 7) {
        //Caso algum número for clicado
        switch (view.getId()) {
            case R.id.button0: //Adicionando o zero no result
                Result[i] = (Result[i] * 10); count++;
                break;
            case R.id.button1: //Adicionando o um no result
                Result[i] = (Result[i] * 10) + 1; count++;
                break;
            case R.id.button2: //Adicionando o dois no result
                Result[i] = (Result[i] * 10) + 2; count++;
                break;
            case R.id.button3: //Adicionando o tres no result
                Result[i] = (Result[i] * 10) + 3; count++;
                break;
            case R.id.button4: //Adicionando o quarto no result
                Result[i] = (Result[i] * 10) + 4; count++;
                break;
            case R.id.button5: //Adicionando o cinco no result
                Result[i] = (Result[i] * 10) + 5; count++;
                break;
            case R.id.button6: //Adicionando o seis no result
                Result[i] = (Result[i] * 10) + 6; count++;
                break;
            case R.id.button7: //Adicionando o sete no result
                Result[i] = (Result[i] * 10) + 7; count++;
                break;
            case R.id.button8: //Adicionando o oito no result
                Result[i] = (Result[i] * 10) + 8; count++;
                break;
            case R.id.button9: //Adicionando o nove no result
                Result[i] = (Result[i] * 10) + 9; count++;
                break;
        }
    }
E por fim chamaremos a função para trocar os resultados na tela e zerar depois o Total (Que será utilizado na função calcular) para não dar erro.
    changesResult();    //Troca o resultado na tela
    Total = 0;          //Zera o velor de total para não dar erro
Para a função do calculo chamada no de switch operadores quando o botão igual for pressionado, ele irá identificar qual operador tinha sido apertado anteriormente, para assim executar a operação. E ele no final checa se o valor é menor que o número do INVALID, para não armazenar caso verdadeiro.
    //Executa as operações
    private void calcular(){
        switch (operator){
            //Executa as operações e sai do switch
            case "soma": Total = (Result[0] + Result[1]); break;
            case "sub": Total = Result[0] - Result[1]; break;
            case "mult": Total = Result[0] * Result[1]; break;
            case "div": Total = Result[0] / Result[1]; break;
        }
        //Se for um valor inválido
        if (Total < INVALID) {
            Result[0] = Total;  //Para executar mais operações
            Result[1] = 0;      //Passa para o segundo valor
            i = 1;
        }
    }
E a ultima função seria para mudar o valor da tela, onde poderá imprimir o valor total, ou o parcial.
    //Troca o resultado na tela
    private void changesResult(){
        if (Total != 0 && Total < INVALID){                   //Se o valor total for válido
            String tela = String.valueOf(Total);
            RESULTSCREEN.setText(tela);
        }else if (Total > INVALID){                           //Se o valor total for inválido
            String tela = "ERROR";
            RESULTSCREEN.setText(tela);
        } else {                                            //Se ainda não foi calculado o resultado
            String tela = String.valueOf(Result[i]);
            RESULTSCREEN.setText(tela);
        }
    }
Disponibilizamos o projeto final do aplicativo pelo GitHub, para que vocês possam fazer Download/Clone do repositório. Link do GitHub: http://github.com/MNascimentoS/App-Calculadora

Um comentário: