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

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

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

    Урок 6. Оптимизируем код. Обрабатываем нажатия дополнительных кнопок.

    Посмотрим на код MainActivity.java. В onCreate у нас 16 однотипных методов findViewById и 16 setOnClickListener. Учитывая , что мы добавили еще 4 кнопки их будет по 20. Еще возьмем в расчет, что вскоре мы будем менять вид кнопок и с каждой из них нам нужно будет проделывать одинаковые операции. Представляете во что превратится наш код! 

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

    Сначала объявим объекты наших новых четырех кнопок, а также для работы нам понадобятся два массива (один типа int - для id кнопок, другой типа Button - для самих объектов кнопок) и целочисленная переменная для хранения количества элементов массива:

    Button btPoint, btSquare, btRadical, btBack;

    int[] bt_ids;

    Button[] bt_array;

    int len;

    Затем удаляем 16 строк findViewById и 16 setOnClickListener, относяшихся к кнопкам. Текстовое поле и LinearLayout  не трогаем, только кнопки.

    Инициализируем массивы, т.е. задаем значения их элементов:

    bt_ids = new int[]{R.id.btOne, R.id.btTwo, R.id.btThree, R.id.btFour,                          R.id.btFive,

                 R.id.btSix, R.id.btSeven, R.id.btEight, R.id.btNine, R.id.btZero,

                 R.id.btPlus, R.id.btMinus,R.id.btMulti, R.id.btDiv, R.id.btEqual,

                 R.id.btClear, R.id.btPoint, R.id.btSquare, R.id.btRadical, R.id.btBack};

    bt_array = new Button[]{btOne, btTwo, btThree, btFour, btFive, btSix,                        btSeven,

                 btEight, btNine,btZero, btPlus, btMinus, btMulti, btDiv, btEqual,

                 btClear, btPoint, btSquare, btRadical, btBack};

    Определяем количество элементов массива и пишем цикл:

           len = bt_array.length;

           for(int i = 0; i < len; i++){

                 bt_array[i] = (Button) findViewById(bt_ids[i]);

                 bt_array[i].setOnClickListener(this);

           }

    Готово! Разберем, что тут происходит: с каждой итерацией (повторением) цикла мы увеличиваем i на единицу, берем i-тый элемент массива bt_array и связываем его с i-тым элементом массива bt_ids. Затем для него устанавливаем слушатель. Переходим к следующей итерации. Так продолжаем, пока i будет меньше, чем количество элементов в массиве. Думаю нужно заметить, что нумерация элементов массива в Java начинается с нуля.

    Заметили как уменьшилось количество кода.

    Если вы заметили, одна из дополнительных кнопок - точка. Мы позже сделаем обработку чисел с запятой. Поэтому нам перед выводом числа в текстовое поле нам понадобится проверка, является ли число дробным, чтобы целые числа отображать без дробной части. Эту проверку нам нужно будет делать перед каждым показом числа на разных участках кода. Что бы не писать один и тот же код в нескольких местах, вынесем проверку и вывод в текстовое поле в отдельный метод showNumber.

           private void showNumber(double num){

                 if(num%1 == 0){

                        tvLCD.setText(Integer.toString((int) num));

                 }else{

                        tvLCD.setText(Double.toString(num));

                 }

           }

    Проверяем равна ли дробная часть нулю, в зависимости от результата выводим число в tvLCD одним из способов. Теперь изменим тип переменных operand1 и operand2 на double (т.к. в будущем будем записывать в них дробные числа, также чтобы избежать ошибок на этом этапе - ведь showNumber просит на вход переменную типа double), а также заменим везде код tvLCD.setText(...) на showNumber(...).

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

    private void clearVariables(){

                 operand1 = 0;

                 operand2 = 0;

                 result = 0;

                 flagAction = 0;

                  }

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

    Теперь возьмемся за обработку нажатий дополнительных кнопок. В этом уроке напишем код обработки кнопок "Получение корня", "Квадрат числа" и "Стереть последний символ". Обработку точки оставляем на следующий урок, т.к. тема довольна объемная.

    Запускаем приложение. Попробуйте деление с дробным и целочисленным результатом.

    В switch в методе onClick добавляем:

                 case R.id.btPoint:

                       

                        break;

                 case R.id.btSquare:

                        if(flagAction == 0){

                               result = Math.pow(operand1, 2);

                               showNumber(result);

                               clearVariables();

                        }else{

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

                        }

                        break;

                 case R.id.btRadical:

                        if(flagAction == 0){

                               result = Math.sqrt(operand1);

                               showNumber(result);

                               clearVariables();

                        }else{

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

                        }

                        break;

                 case R.id.btBack:

                        String Temp;

                        if(flagAction == 0){

                               if(operand1%1 == 0){

                                      Temp = Integer.toString((int)operand1);

                               }else{Temp = Double.toString(operand1);}

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

                               if(Temp.length() > 0){

                               operand1 = Double.parseDouble(Temp);

                               }else{operand1 = 0;}

                               showNumber(operand1);

                        }else{

                               if(operand2%1 == 0){

                                      Temp = Integer.toString((int)operand2);

                               }else{Temp = Double.toString(operand2);}

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

                               if(Temp.length() > 0){

                                      operand2 = Double.parseDouble(Temp);

                               }else{operand2 = 0;}

                               showNumber(operand2);

                        }

                        break;

    Первый case пустой - там будет обработка нажатия точки. Во втором и третьем проверяем не нажата ли кнопка другой операции, если нет совершаем операцию над первым операндом (возводим в квадрат или извлекаем корень), выводим результат, обнуляем переменные, иначе сообщаем пользователю, что выбрана другая операция. Текст сообщения снова берем из string.xml, где добавляем еще одну константу:

    <string name="other_operation">Уже задана другая операция</string>

    В четвертом стираем последнюю введенную цифру. Можно было бы решить эту задачу действиями с числовыми переменными, но мне показалось, что код получится большим. Поэтому я решил удалять последний символ из промежуточной строковой переменной, а затем возвращать её в double. Возможно кто-то посчитает такой подход костылем, но мне так больше нравится. Алгоритм такой - проверяем flagAction, если он равен нулю, кнопка действия еще не нажата - редактируем первый операнд, иначе второй. Затем проверяем, есть ли у числа дробная часть. В зависимости от результата, формируем строковую переменную. Удаляем из нее последний символ. Проверяем не пустая ли строка (она будет пустой в случае, если до удаления строка состояла из одного символа). Если не пустая парсим её в double. Если пустая просто присваиваем ноль.

    Запускаем в эмуляторе. Пробуем новые кнопки.

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

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

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

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

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

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

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

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

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

    Листинг MainActivity.java

    package ru.urok.super_calc;

     

    import android.app.Activity;

    import android.content.Intent;

    import android.content.SharedPreferences;

    import android.os.Bundle;

    import android.preference.PreferenceManager;

    import android.view.Menu;

    import android.view.MenuItem;

    import android.view.View;

    import android.view.View.OnClickListener;

    import android.widget.Button;

    import android.widget.LinearLayout;

    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;

           Button btPoint, btSquare, btRadical, btBack;

           TextView tvLCD;

           //объявляем переменные для вычислений

           double operand1, operand2;

           int flagAction;

           double result;

           SharedPreferences sp;

           Boolean add_button;

           String style_calc;

           LinearLayout llExtra;

           int[] bt_ids;

           Button[] bt_array;

           int len;

     

           @Override

           protected void onCreate(Bundle savedInstanceState) {

                 super.onCreate(savedInstanceState);

                 setContentView(R.layout.activity_main);

                 sp = PreferenceManager.getDefaultSharedPreferences(this);

                 tvLCD = (TextView) findViewById(R.id.tvLCD);

                 llExtra = (LinearLayout) findViewById(R.id.llExtra);

                

                 bt_ids = new int[]{R.id.btOne, R.id.btTwo, R.id.btThree, R.id.btFour, R.id.btFive,

                               R.id.btSix, R.id.btSeven, R.id.btEight, R.id.btNine, R.id.btZero,

                               R.id.btPlus, R.id.btMinus,R.id.btMulti, R.id.btDiv, R.id.btEqual,

                               R.id.btClear, R.id.btPoint, R.id.btSquare, R.id.btRadical,                             R.id.btBack};

                 bt_array = new Button[]{btOne, btTwo, btThree, btFour, btFive, btSix, btSeven,

                               btEight, btNine,btZero, btPlus, btMinus, btMulti, btDiv, btEqual,

                               btClear, btPoint, btSquare, btRadical, btBack};

                 len = bt_array.length;

                 for(int i = 0; i < len; i++){

                        bt_array[i] = (Button) findViewById(bt_ids[i]);

                        bt_array[i].setOnClickListener(this);

                 }

                

                 //инициализируем переменные

                 clearVariables();

                 //Установим значение первого операнда в текстовое поле

                 showNumber(operand1);

                       

           }

          

           protected void onResume() {

               add_button = sp.getBoolean("add_button", false);

               style_calc = sp.getString("style_calc", "1");

               int flag_visiblity = View.INVISIBLE;

               if(add_button)flag_visiblity = View.VISIBLE;

               llExtra.setVisibility(flag_visiblity);

               super.onResume();

             }

     

           @Override

           public boolean onCreateOptionsMenu(Menu menu) {

                 getMenuInflater().inflate(R.menu.main, menu);

                 return true;

           }

     

           @Override

           public boolean onOptionsItemSelected(MenuItem item) {

                 switch(item.getItemId()){

                 case R.id.options_menu:

                        startActivity(new Intent(this, PrefActivity.class));

                        break;

                 case R.id.about_menu:

                        startActivity(new Intent(this, AboutActivity.class));

                        break;

                

                 }

                 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.btPoint:

                       

                        break;

                 case R.id.btSquare:

                        if(flagAction == 0){

                               result = Math.pow(operand1, 2);

                               showNumber(result);

                               clearVariables();

                        }else{

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

                        }

                        break;

                 case R.id.btRadical:

                        if(flagAction == 0){

                               result = Math.sqrt(operand1);

                               showNumber(result);

                               clearVariables();

                        }else{

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

                        }

                        break;

                 case R.id.btBack:

                        String Temp;

                        if(flagAction == 0){

                               if(operand1%1 == 0){

                                      Temp = Integer.toString((int)operand1);

                               }else{Temp = Double.toString(operand1);}

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

                               if(Temp.length() > 0){

                               operand1 = Double.parseDouble(Temp);

                               }else{operand1 = 0;}

                               showNumber(operand1);

                        }else{

                               if(operand2%1 == 0){

                                      Temp = Integer.toString((int)operand2);

                               }else{Temp = Double.toString(operand2);}

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

                               if(Temp.length() > 0){

                                      operand2 = Double.parseDouble(Temp);

                               }else{operand2 = 0;}

                               showNumber(operand2);

                        }

                        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){

                               showNumber(result);

                               clearVariables();

                        }

                        break;

                 case R.id.btClear:

                        clearVariables();

                        showNumber(operand1);

                        break;

                 }

           }

          

           private void ClickNumber(int num){

                 if(flagAction == 0){

                        operand1 = operand1*10 + num;

                        showNumber(operand1);

                 }else{

                        operand2 = operand2*10 + num;

                        showNumber(operand2);

                 }

           }

          

           private void showNumber(double num){

                 if(num%1 == 0){

                        tvLCD.setText(Integer.toString((int) num));

                 }else{

                        tvLCD.setText(Double.toString(num));

                 }

           }

           private void clearVariables(){

                 operand1 = 0;

                 operand2 = 0;

                 result = 0;

                 flagAction = 0;

           }

    }

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

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