Програмуємо калькулятор на андроїд. Урок 2

Урок другий. Пишемо функціонал додатку.

Для функціоналу нам знадобляться числові змінні – operand1, operand2 (для зберігання чисел, з якими будуть відбуватися операції), result (для зберігання результату операції) і flagAction (тут буде зберігатися код операції).

Оголошуємо змінні перед методом onCreate:

int operand1, operand2, flagAction;
double result;

Оскільки ми не ввели кнопку “.”, Працювати будемо тільки з цілочисельними операндами. Тому оголошуємо їх з типом int. А результат може бути дробовим  числом (наприклад, 5/2), тому змінна result буде з плаваючою комою типу double.

В змінної flagAction зберігаємо код операції: 0 – немає операції, 1 – складання, 2 віднімання, 3 – множення, 4 – розподіл.

У методі onCreate оголосимо змінні за допомогою нулів:

   operand1 = 0;
   operand2 = 0;
   result = 0;
   flagAction = 0;

Встановимо значення першого операнда у текстове поле:

tvLCD.setText (Integer.toString (operand1));

Зверніть увагу, що ми передаємо в метод setText операнд у вигляді String.

Тепер переходимо до методу onClick. Дії визначаються в залежності від натиснутої кнопки, для цього в операторі switch визначаємо id натиснутою кнопки. Потім порівнюємо його з id всіх кнопок. Якщо є збіг, виконуємо тіло відповідного оператора case.

Натискання на цифрові кнопки будемо обробляти в окремому методі, в який будемо передавати натиснуту цифру. Сам метод потрібно створювати вручну:

private void ClickNumber(int num){
if(flagAction == 0){
   operand1 = operand1*10 + num;
   tvLCD.setText(Integer.toString(operand1)); 
}else{
   operand2 = operand2*10 + num;
   tvLCD.setText(Integer.toString(operand2)); 
   } 
}

Тут ми перевіряємо flagAction – якщо він дорівнює нулю, змінюємо значення першого операнда, якщо немає, то другого. Потім змінюємо значення текстового поля на актуальне значення операнда.

При натисканні на кнопки дій (додавання, віднімання, ділення, множення) просто присвоюємо flagAction відповідне значення, якщо воно ще не присвоєно. Зверніть увагу, що якщо значення прапора відмінно від нуля, ніяких дій проводиться не буде.

При натисканні кнопки “С” присвоюємо всім змінним нуль і актуалізуємо текстове поле.

При натисканні на кнопку дорівнює перевіряємо значення flagAction і виконуємо відповідну операцію, виводимо результат в tvLCD і Обнуляємо змінні. Якщо значення flagAction не відповідає жодній дії повідомляємо про це користувачеві.

switch(flagAction){ 
case 1: 
   result = operand1 + operand2;
   break; 
case 2: 
   result = operand1 - operand2; 
   break; 
case 3: 
   result = operand1 * operand2; 
   break; 
case 4: 
   result =(double) operand1 / (double) operand2; 
   break; 
default: 
   Toast.makeText(this, "Операцію не задано", Toast.LENGTH_LONG); 
}
if(flagAction != 0){
   tvLCD.setText(Double.toString(result));
   operand1 = 0;  
   operand2 = 0;
   result = 0; 
   flagAction = 0;
 }

Здається все. Можна запускати калькулятор на емуляторі. Можливості його, звичайно, до повнофункціонального калькулятора не дотягують, але для демонстрації роботи коду досить.

Відразу зазначу, я не вводив ніяких перевірок на помилки, щоб не робити код занадто довгим. Наприклад, якщо спробувати ввести дуже велике число, в текстовому полі будуть відображатися неадекватні числа. Це відбувається через обмеження довжини змінної типу int чотирма байтами. При переповненні розрядності система відкидає зайві розряди до довжини в 4 байта і присвоює отримане число змінної. При написанні програми розробник повинен врахувати такі помилки і передбачити їх виникнення.

У макеті нічого не змінювалося тому наводжу тільки код MainActivity.java

package ru.urok.super_calc;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {
//объявляем кнопки и текстовое поле
Button btOne, btTwo, btThree, btFour, btFive;
Button btSix, btSeven, btEight, btNine, btZero;
Button btPlus, btMinus, btMulti, btDiv, btEqual, btClear;
TextView tvLCD;
//объявляем переменные для вычислений
int operand1, operand2, flagAction;
double result;

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

//связываем кнопки с макетом
   btOne = (Button) findViewById(R.id.btOne);
   btTwo = (Button) findViewById(R.id.btTwo);
   btThree = (Button) findViewById(R.id.btThree);
   btFour = (Button) findViewById(R.id.btFour);
   btFive = (Button) findViewById(R.id.btFive);
   btSix = (Button) findViewById(R.id.btSix);
   btSeven = (Button) findViewById(R.id.btSeven);
   btEight = (Button) findViewById(R.id.btEight);
   btNine = (Button) findViewById(R.id.btNine);
   btZero = (Button) findViewById(R.id.btZero);
   btPlus = (Button) findViewById(R.id.btPlus);
   btMinus = (Button) findViewById(R.id.btMinus);
   btMulti = (Button) findViewById(R.id.btMulti);
   btDiv = (Button) findViewById(R.id.btDiv);
   btEqual = (Button) findViewById(R.id.btEqual);
   btClear = (Button) findViewById(R.id.btClear);
   tvLCD = (TextView) findViewById(R.id.tvLCD);
//назначаем кнопкам слушателя
   btOne.setOnClickListener(this);
   btTwo.setOnClickListener(this);
   btThree.setOnClickListener(this);
   btFour.setOnClickListener(this);
   btFive.setOnClickListener(this);
   btSix.setOnClickListener(this);
   btSeven.setOnClickListener(this);
   btEight.setOnClickListener(this);
   btNine.setOnClickListener(this);
   btZero.setOnClickListener(this);
   btPlus.setOnClickListener(this);
   btMinus.setOnClickListener(this);
   btMulti.setOnClickListener(this);
   btDiv.setOnClickListener(this);
   btClear.setOnClickListener(this);
   btEqual.setOnClickListener(this);

//Оголошуємо змінні
   operand1 = 0;
   operand2 = 0;
   result = 0;
   flagAction = 0;
//Встановимо значення першого операнду в текстове поле
   tvLCD.setText(Integer.toString(operand1));
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
   getMenuInflater().inflate(R.menu.main, menu);
   return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
   int id = item.getItemId();
   if (id == R.id.action_settings) {
   return true;
   }
   return super.onOptionsItemSelected(item);
}

@Override
public void onClick(View v) {
   switch(v.getId()){
   case R.id.btOne:
   ClickNumber(1);
   break;
   case R.id.btTwo:
   ClickNumber(2);
   break;
   case R.id.btThree:
   ClickNumber(3);
   break;
   case R.id.btFour:
   ClickNumber(4);
   break;
   case R.id.btFive:
   ClickNumber(5);
   break;
   case R.id.btSix:
   ClickNumber(6);
   break;
   case R.id.btSeven:
   ClickNumber(7);
   break;
   case R.id.btEight:
   ClickNumber(8);
   break;
   case R.id.btNine:
   ClickNumber(9);
   break;
   case R.id.btZero:
   ClickNumber(0);
   break;
   case R.id.btPlus:
   if(flagAction == 0)flagAction = 1;
   break;
   case R.id.btMinus:
   if(flagAction == 0)flagAction = 2;
   break;
   case R.id.btMulti:
   if(flagAction == 0)flagAction = 3;
   break;
   case R.id.btDiv:
   if(flagAction == 0)flagAction = 4;
   break;
   case R.id.btEqual:
   switch(flagAction){
   case 1:
      result = operand1 + operand2;
   break;
   case 2:
      result = operand1 - operand2;
   break;
   case 3:
      result = operand1 * operand2;
   break;
   case 4:
      result =(double) operand1 / (double) operand2;
   break;
   default:
      Toast.makeText(this, "Операцію не задано", Toast.LENGTH_LONG).show();
   }
   if(flagAction != 0){
      tvLCD.setText(Double.toString(result));
      operand1 = 0;
      operand2 = 0;
      result = 0;
      flagAction = 0;
   }
   break;
   case R.id.btClear:
      operand1 = 0;
      operand2 = 0;
      result = 0;
      flagAction = 0;
      tvLCD.setText(Integer.toString(operand1));
   break;
   }
}

private void ClickNumber(int num){
   if(flagAction == 0){
      operand1 = operand1*10 + num;
      tvLCD.setText(Integer.toString(operand1));
   }else{
     operand2 = operand2*10 + num;
     tvLCD.setText(Integer.toString(operand2));
     }
   }
}