Вторник, 20.11.2018, 19:06
Поиск
Никнэйм
Сертификат на никнейм Olelucoye, зарегистрирован на Тимофеев Константин Михайлович
Зарегистрируй свой никнейм
Обратная связь
olelucoye.tk@yandex.ru
Реклама AdSense
Реклама
Друзья сайта
  • Лига медицинского права
  • Гостиница "Зай"
  • FAQ по системе
  • Инструкции для uCoz
  • Главная » Статьи » Андроид разработка

    Программируем калькулятор на андроид. Урок 9.

    Урок сделан специально для группы http://vk.com/amdroid.developer

    Урок 9. Новая система расчета и вывода чисел на экран.

    Предыдущий способ функционирования калькулятора оказался не очень удачным. Поэтому я решил пересмотреть код.

    Перебрав несколько вариантов, я остановился на таком: операнды храним в текстовых переменных, парсим их в double непосредственно во время вычислений. Результат преобразуем в строку перед выводом в текстовое поле. Ограничение разрядности теперь не отдельно для целой и дробной части числа, а общее, т.е. сумма целых и дробных разрядов не должна превышать максимальной длины числа. Также предусмотрена проверка деления на ноль и еще кое-какие мелочи. Число отображается корректно на всех этапах вычислений. Все изменения касаются только MainActivity.java. Интерфейс не менял

    Рассмотрим подробнее.

    Для работы с вычислениями и отображением чисел в текстовом поле нам нужны будут переменные:

    Boolean flagPoint;

    String operand1, operand2;

    int flagAction;

    double result;

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

           @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.btNine:

                        ClickNumber("9");

                        break;

                 case R.id.btZero:

                        if(flagAction == 0){

                               if(operand1.length() != 0)ClickNumber("0");

                        }else{

                               if(operand2.length() != 0)ClickNumber("0");

                        }

                        break;

    При нажатии нуля проверяем не был ли ноль первым нажатым символом, если да - ничего не передаем в ClickNumber. При нажатии на точку, проверяем flagPoint, т.е. не была ли уже нажата точка. Затем проверяем flagAction, т.е. определяем какой операнд изменяем. Проверяем не первый ли символ в операнде точка, если нет - посылаем в ClickNumber ".", иначе - "0." flagPoint присваиваем true, т.е. точка уже нажата.

                 case R.id.btPoint:

                        if(!flagPoint){

                        if(flagAction == 0){

                               if(operand1.length() != 0){

                                      ClickNumber(".");

                               }else{ClickNumber("0.");

                               }

                        }else{

                               if(operand2.length() != 0){

                                      ClickNumber(".");

                               }else{ClickNumber("0.");}

                               flagPoint = true;

                        }

                        }

    При нажатии на действия присваиваем flagAction номер действия, flagPoint присваиваем false, т.к. переходим к вводу второго операнда, а для него точка еще не нажата.

                 case R.id.btPlus:

                        if(flagAction == 0){

                               flagAction = 1;

                               flagPoint = false;

                        }

                        break;

                 case R.id.btMinus:

                        if(flagAction == 0){

                               flagAction = 2;

                               flagPoint = false;

                        }

                        break;

                 case R.id.btMulti:

                        if(flagAction == 0){

                               flagAction = 3;

                               flagPoint = false;

                        }

                        break;

                 case R.id.btDiv:

                        if(flagAction == 0){

                               flagAction = 4;

                               flagPoint = false;

                        }

    Нажатия на корень и квадрат числа. Проверяем не выбрана ли уже другая операция, если выбрана сообщаем об этом пользователю. Затем проверяем не пустой ли первый операнд, если пустой, присваиваем ему значение "0". Совершаем математическую операцию. Передаем результат в showNumber. Поскольку result имеет тип double, предварительно обрабатываем его функцией procNumber, которую рассмотрим ниже.

           case R.id.btSquare:

                        if(flagAction == 0){

                               if(operand1.length() == 0)operand1 = "0";

                               result = Math.pow(Double.parseDouble(operand1), 2);

                               showNumber(procNumber(result));

                               clearVariables();

                        }else{

                               Toast.makeText(this, R.string.other_operation,                                                Toast.LENGTH_LONG).show();

                        }

                        break;

                 case R.id.btRadical:

                        if(flagAction == 0){

                               if(operand1.length() == 0)operand1 = "0";

                               result = Math.sqrt(Double.parseDouble(operand1));

                               showNumber(procNumber(result));

                               clearVariables();

                        }else{

                               Toast.makeText(this, R.string.other_operation,                                                Toast.LENGTH_LONG).show();

                        }

    При нажатии на равно, проверяем операнды на пустоту, если пустые присваиваем ноль. В зависимости от значения flagAction совершаем математическую операцию. При делении проверяем второй операнд на ноль, чтобы не вызвать ошибку (на ноль делить ведь нельзя). Посылаем результат в showNumber, предварительно обрабатываем его функцией procNumber. Обнуляем переменные.

                 case R.id.btEqual:

                        if(operand1.length() == 0)operand1 = "0";

                        if(operand2.length() == 0)operand2 = "0";

                        switch(flagAction){

                               case 1:

                                     result = Double.parseDouble(operand1) +                                                Double.parseDouble(operand2);

                                      showNumber(procNumber(result));

                                      clearVariables();

                                      break;

                               case 2:

                                      result = Double.parseDouble(operand1) -                                                Double.parseDouble(operand2);

                                      showNumber(procNumber(result));

                                      clearVariables();

                                      break;

                               case 3:

                                      result = Double.parseDouble(operand1) *                                                Double.parseDouble(operand2);

                                      showNumber(procNumber(result));

                                      clearVariables();

                                      break;

                               case 4:

                                      if(Double.parseDouble(operand2) != 0){

                                      result = Double.parseDouble(operand1) /                                                Double.parseDouble(operand2);

                                      }

                                      showNumber(procNumber(result));

                                      clearVariables();

                                      break;

                               default:

                                      Toast.makeText(this, R.string.no_operation,                                                   Toast.LENGTH_LONG).show();

                               }

                        break;

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

                 case R.id.btClear:

                        clearVariables();

                        showNumber(operand1);

                        break;

    Метод ClickNumber (вызываем при нажатии на цифры). Проверяем flagAction, что бы определить какой операнд меняем. Функцией checkOver (рассмотрим ниже) проверяем не достиг ли операнд максимальной разрядности. Если достиг - сообщение, если нет - добавляем к операнду нажатый символ. Выводим в текстовое поле.

           private void ClickNumber(String num){

                 if(flagAction == 0){

                        if(checkOver(operand1)){

                               Toast.makeText(this, R.string.limit,                                                          Toast.LENGTH_LONG).show();

                        }else{

                               operand1 = operand1 + num;

                               showNumber(operand1);

                        }

                 }else{

                        if(checkOver(operand2)){

                               Toast.makeText(this, R.string.limit,                                                          Toast.LENGTH_LONG).show();

                        }else{

                               operand2 = operand2 + num;

                               showNumber(operand2);

                        }

                 }

           }

    Метод showNumber (вывод в текстовое поле). Если переданный параметр пустой (когда в операнд не ввели ни одного символа), присваиваем ему ноль. Выводим на экран. Если переданный параметр равен "error" (может возникнуть при обработке функцией procNumber), показываем пользователю сообщение об ошибке.

           private void showNumber(String num){

                 if(num.length() == 0)num = "0";

                 tvLCD.setText(num);

                 if(num.equals("error"))Toast.makeText(this, R.string.degree_overflow,                         Toast.LENGTH_LONG).show();

           }

    Очистка переменных. Тут вроде всё понятно.

           private void clearVariables(){

                 operand1 = "";

                 operand2 = "";

                 result = 0;

                 flagAction = 0;

                 flagPoint = false;

           }

    Проверка на максимальную разрядность. Если параметр достиг длины в 10 символов, без учета точки, возвращаем истину, иначе ложь. Вспомните обычный калькулятор - на нем ведь нельзя ввести больше цифр, чем предусмотрено разрядов производителем. У нас будет 10-ти разрядный калькулятор.

           private boolean checkOver(String var){

                 int corr = 0;

                 if(var.contains("."))corr = 1;

                 if(var.length()-corr == 10){

                        return true;

                 }else{return false;}

           }

    Функция procNumber подготавливает double переменную к выводу на экран. Разделяем переданный параметр на целую и дробную часть, записываем части в две переменные типа long. Если дробная часть равна нулю, парсим целую часть в строку. Если длина строки больше 10 символов (превышает количество разрядов "на экране" нашего калькулятора) в строковую переменную записываем "error". Если число с дробной частью, снова проверяем длину целой части, но теперь сравниваем его с девяткой (нам ведь нужно вывести хоть один символ дробной части). Если превышает - записываем в num ошибку, если нет, то к целой части добавляем точку и дробную часть округленную до количества символов оставшихся после записи в строковую переменную целой части, т.е. если целая часть заняла 7 символов, дробная часть будет округлена до 3 символов.

    В цикле while стираем все лишние нули в конце дробной части числа. Возвращаем полученную строку

    private String procNumber(double res){

                 String num;

                 long part_int = (long) (res - res%1);

                 long part_frac = Math.round(res%1 * 1000000000);

                 if(part_frac == 0){

                        num = Long.toString(part_int);

                        if(num.length() > 10)num ="error";

                 }else{

                        if(Long.toString(part_int).length() > 9){

                               num ="error";

                        }else{

                               num = Long.toString(part_int) + "." +                                                         Long.toString(Math.round(part_frac /

                                      Math.pow(10, Long.toString(part_int).length()-1)));

                        }

                 }

                

                 while(num.substring(num.length()-1, num.length()).equals("0") &                                            num.length() == 0){

                        num = num.substring(0, num.length()-1);

                 }

                 return num;

           }

    В string.xml убираем константы limit_before и limit_after. Вместо них одна общая константа:

    <string name="limit">Ограничение разрядности = 10</string>

    Здесь можно посмотреть Полный листинг MainActivity.java 

    А здесь можно взять получившийся apk-файл (неподписанный).

    Программируем калькулятор на андроид. Урок 10.

    Программируем калькулятор на андроид. Урок 8.

    Программируем калькулятор на андроид. Урок 7.

    Программируем калькулятор на андроид. Урок 6.

    Программируем калькулятор на андроид. Урок 5.

    Программируем калькулятор на андроид. Урок 4.

    Программируем калькулятор на андроид. Урок 3.

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

    Программируем калькулятор на андроид. Урок 1.

     

    Категория: Андроид разработка | Добавил: Olelucoye (04.12.2014)
    Просмотров: 1840
    | Теги: Калькулятор, java, Android | Рейтинг: 0.0/0
    Всего комментариев: 0
    Добавлять комментарии могут только зарегистрированные пользователи.
    [ Регистрация | Вход ]
    Меню сайта
    Категории раздела
    Андроид разработка [23]
    libGDX [24]
    Мои андроид проекты [6]
    Excel [7]
    Железяки [5]
    Скрипты в блокноте [4]
    Разное [1]
    Форма входа
    Статистика

    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0
    Яндекс Метрика
    Яндекс.Метрика