Создание калькулятора чаевых на Kotlin: как это работает?

Создание калькулятора чаевых на Kotlin: как это работает?

Рассказываем, как создать простое приложение для расчета чаевых на языке Kotlin. Если точнее, то Kotlin 1.3.21, Android 4, Android Studio 3. Статья будет интересной, в первую очередь, для тех, кто начинает свой путь в разработке Android-приложений. Она позволяет понять, что и как работает внутри приложения.

Такой калькулятор пригодится, когда нужно подсчитать сумму чаевых с компании, решившей провести время в ресторане или кафе. Конечно, не все и не всегда оставляют официантам на чай, это больше западная традиция, но процесс разработки такого приложения в любом случае интересен.

Напоминаем: для всех читателей «Хабра» — скидка 10 000 рублей при записи на любой курс Skillbox по промокоду «Хабр».

Skillbox рекомендует: Практический курс «Мобильный разработчик PRO.

Вот как выглядит приложение в процессе работы:

Создание калькулятора чаевых на Kotlin: как это работает?

Вы вводите желаемый процент с общей суммы, количество участников встречи и получаете результат — сумму чаевых, которые стоит оставить.

Начинаем

Полный интерфейс приложения выглядит следующим образом:
Создание калькулятора чаевых на Kotlin: как это работает?

Создание калькулятора чаевых на Kotlin: как это работает?

Первое действие — загрузка основы проекта. Открываем ее в Android Studio 3.0 или более поздней версии. Строим и запускаем проект и видим белый экран. Все нормально, так и должно быть.

Создание калькулятора чаевых на Kotlin: как это работает?

Создание калькулятора чаевых на Kotlin: как это работает?

Действия пользователя прописаны в проекте в хронологическом порядке, чтобы все было понятно. Для его просмотра открываем View -> Tool Windows -> TODO.

Изучаем проект и открываем colors.xml для оценки цветовой палитры. В strings.xml размещены текстовые данные (подписи), а в styles.xml есть несколько шрифтовых шаблонов.

Разработка раздела затрат

Открываем activity_main.xml и добавляем расположенный ниже код в LinearLayout (#1):

<TextView
    android_id="@+id/expensePerPersonTextView"
    android_layout_width="match_parent"
    android_layout_height="wrap_content"
    android_paddingTop="30dp"
    style="@style/h1Bold"
    android_textColor="@color/colorAccent"
    android_text="0"/>
 
<TextView
    android_layout_width="match_parent"
    android_layout_height="wrap_content"
    android_paddingBottom="25dp"
    style="@style/h2"
    android_textColor="@color/colorAccent"
    android_text="@string/perPersonStaticText"/>

Теперь можно настроить стиль директории values или поиграть с цветами, используя инструмент material.io.

Сейчас проект выглядит так:

Создание калькулятора чаевых на Kotlin: как это работает?
Как видите, расчет затрат производится по данным, которые вносит пользователь.

Разработка раздела счетов

Добавляем код, размещенный ниже, в LinearLayout после Expense Section (#2):

<LinearLayout
    android_layout_width="match_parent"
    android_layout_height="match_parent"
    android_orientation="vertical"
    android_background="@color/colorAccent">
 
<! — TODO #3: Build Bill Section →
 
… 
</LinearLayout>

Закрываем LinearLayout после списка TODOs, а затем добавляем новый код, размещая его внутри LinearLayout (#3):

<TextView
      android_layout_margin="15dp"
      android_layout_width="match_parent"
      android_layout_height="wrap_content"
      android_textColor="@color/colorWhite"
      style="@style/h4"
      android_text="@string/billStaticText"/>
 
<EditText
      android_id="@+id/billEditText"
      android_layout_width="match_parent"
      android_layout_height="wrap_content"
      android_textColor="@color/colorWhite"
      android_inputType="numberDecimal"
      android_maxLines="1"
      style="@style/h2Bold"
      android_text="0"/>

Поскольку главная задача приложения — расчет индивидуальных затрат для каждого из участников посиделок в ресторане, то основное значение играет costPerPersonTextView.

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

Создание калькулятора чаевых на Kotlin: как это работает?
Запускаем проект для теста и вводим параметры общего ущерба (разбитые чашки, тарелки и т.п.)

Разработка раздела «Люди и чаевые»

Чтобы добавить выбора объема чаевых, вставляем расположенный ниже код в новую секцию LinearLayout (#4):

<TextView
      android_layout_margin="15dp"
      android_layout_width="match_parent"
      android_layout_height="wrap_content"
      android_textColor="@color/colorWhite"
      style="@style/h4"
      android_text="@string/tipStaticText"/>
 
<LinearLayout
      android_layout_width="match_parent"
      android_layout_height="wrap_content"
      android_orientation="horizontal">
 
<ImageButton
        android_id="@+id/subtractTipButton"
        style="@style/operationButton"
        android_layout_marginLeft="20dp"
        android_layout_marginStart="20dp"
        android_src="@drawable/subtract"/>
 
<TextView
        android_id="@+id/tipTextView"
        android_layout_margin="15dp"
        android_layout_width="0dp"
        android_layout_height="wrap_content"
        android_textColor="@color/colorWhite"
        android_layout_weight="1"
        style="@style/h2Bold"
        android_text="20%"/>
 
<ImageButton
        android_id="@+id/addTipButton"
        style="@style/operationButton"
        android_layout_marginEnd="20dp"
        android_layout_marginRight="20dp"
        android_src="@drawable/add"/>
 
</LinearLayout>

Этот участок кода необходим для точного расчета суммы чаевых. Дефолтное значение текста — 20. ImageButtons снабжены иконками в папке с правами записи.

Полностью копируем раздел и добавляем следующее (#5):

  • ImageButton ids (subtractPeopleButton, addPeopleButton)
  • TextView ids (numberOfPeopleStaticText, numberOfPeopleTextView)
  • DefaultText для numberOfPeopleTextView (должен быть 4).

Создание калькулятора чаевых на Kotlin: как это работает?

Теперь при запуске приложения есть возможность добавить сумму счета, также работают кнопки «Добавить/Вычесть», но пока ничего не происходит.

Добавляем Views

Открываем MainActivity.kt и добавляем вот это в функцию initViews (#6):

private fun initViews() {
        expensePerPersonTextView = findViewById(R.id.expensePerPersonTextView)
        billEditText = findViewById(R.id.billEditText)
 
addTipButton = findViewById(R.id.addTipButton)
        tipTextView = findViewById(R.id.tipTextView)
        subtractTipButton = findViewById(R.id.subtractTipButton)
 
addPeopleButton = findViewById(R.id.addPeopleButton)
        numberOfPeopleTextView = findViewById(R.id.numberOfPeopleTextView)
        subtractPeopleButton = findViewById(R.id.subtractPeopleButton)
 
//TODO #8: Bind Buttons to Listener
 
//TODO #16: Bind EditText to TextWatcher
 
}

Доделываем кнопки

Чтобы добавить поддержку клика кнопок, внедряем View.OnClickListener на уровне класса (#7):

class MainActivity: AppCompatActivity(), View.OnClickListener {

Скомпилировать проект прямо сейчас не выйдет, нужно выполнить еще несколько действий (#8):

override fun onClick(v: View?) {
        when (v?.id) {
            R.id.addTipButton -> incrementTip()
            R.id.subtractTipButton -> decrementTip()
            R.id.addPeopleButton -> incrementPeople()
            R.id.subtractPeopleButton -> decrementPeople()
        }
    }

В плане кнопок и свитчей у Kotlin все организовано очень круто! Добавляем размещенный ниже код во все функции increment и decrement
(#9 –#12):

private fun incrementTip() {
        if (tipPercent != MAX_TIP) {
            tipPercent += TIP_INCREMENT_PERCENT
            tipTextView.text = String.format("%d%%", tipPercent)
        }
    }
 
private fun decrementTip() {
        if (tipPercent != MIN_TIP) {
            tipPercent -= TIP_INCREMENT_PERCENT
            tipTextView.text = String.format("%d%%", tipPercent)
        }
    }
 
private fun incrementPeople() {
        if (numberOfPeople != MAX_PEOPLE) {
            numberOfPeople += PEOPLE_INCREMENT_VALUE
            numberOfPeopleTextView.text = numberOfPeople.toString()
        }
    }
 
private fun decrementPeople() {
        if (numberOfPeople != MIN_PEOPLE) {
            numberOfPeople -= PEOPLE_INCREMENT_VALUE
            numberOfPeopleTextView.text = numberOfPeople.toString()
        }
    }

Здесь код защищает функции приращения с максимальными значениями (MAX_TIP & MAX_PEOPLE). Кроме того, код защищает функции декремента с минимальными значениями (MIN_TIP & MIN_PEOPLE).

Теперь связываем кнопки со слушателями в функции initViews (#13):

private fun initViews() {
 
...
 
addTipButton.setOnClickListener(this)
        subtractTipButton.setOnClickListener(this)
 
addPeopleButton.setOnClickListener(this)
        subtractPeopleButton.setOnClickListener(this)
 
//TODO #15: Bind EditText to TextWatcher
}

Создание калькулятора чаевых на Kotlin: как это работает?

Теперь можно добавлять общий ущерб, чаевые и количество участников встречи. Ну и теперь самое главное…

Раздел подсчета затрат

Этот код подсчитывает затраты (#14):

private fun calculateExpense() {
 
val totalBill = billEditText.text.toString().toDouble()
 
val totalExpense = ((HUNDRED_PERCENT + tipPercent) / HUNDRED_PERCENT) * totalBill
        val individualExpense = totalExpense / numberOfPeople
 
expensePerPersonTextView.text = String.format("$%.2f", individualExpense)
 
}

Ну а здесь вызывается функция, которая дает возможность учесть количество людей в компании и подсчитать чаевые (#15):

private fun incrementTip() {
 
…
 
}
 
private fun decrementTip() {
 
…
 
}
 
private fun incrementPeople() {
 
…
 
}
 
private fun decrementPeople() {
 
…
 
}

Запускаем приложение. Выглядит и работает оно отлично. Но может быть и лучше.

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

Финальные шаги

Добавляем TextWatcher (#16):

class MainActivity: AppCompatActivity(), View.OnClickListener, TextWatcher {

Затем встраиваем слушатель billEditText (#17):

billEditText.addTextChangedListener(this)

Плюс добавляем код для выполнения TextWatcher (#18):

override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
        if (!billEditText.text.isEmpty()) {
            calculateExpense()
        }
    }
override fun afterTextChanged(s: Editable?) {}

    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

Создание калькулятора чаевых на Kotlin: как это работает?

Ну а теперь работает абсолютно все! Поздравляю, вы написали собственный «Калькулятор чаевых» на Kotlin.

Создание калькулятора чаевых на Kotlin: как это работает?

Skillbox рекомендует:

Источник: habr.com

Добавить комментарий