- PVSM.RU - https://www.pvsm.ru -
Рассказываем, как создать простое приложение для расчета чаевых на языке Kotlin. Если точнее, то Kotlin 1.3.21, Android 4, Android Studio 3. Статья будет интересной, в первую очередь, для тех, кто начинает свой путь в разработке Android-приложений. Она позволяет понять, что и как работает внутри приложения.
Такой калькулятор пригодится, когда нужно подсчитать сумму чаевых с компании, решившей провести время в ресторане или кафе. Конечно, не все и не всегда оставляют официантам на чай, это больше западная традиция, но процесс разработки такого приложения в любом случае интересен.
Напоминаем: для всех читателей «Хабра» — скидка 10 000 рублей при записи на любой курс Skillbox по промокоду «Хабр».
Skillbox рекомендует: Практический курс «Мобильный разработчик PRO [1].
Вот как выглядит приложение в процессе работы:
Вы вводите желаемый процент с общей суммы, количество участников встречи и получаете результат — сумму чаевых, которые стоит оставить.
Полный интерфейс приложения выглядит следующим образом:
Первое действие — загрузка основы проекта [2]. Открываем ее в Android Studio 3.0 или более поздней версии. Строим и запускаем проект и видим белый экран. Все нормально, так и должно быть.
Действия пользователя прописаны в проекте в хронологическом порядке, чтобы все было понятно. Для его просмотра открываем 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 [3].
Сейчас проект выглядит так:
Как видите, расчет затрат производится по данным, которые вносит пользователь.
Добавляем код, размещенный ниже, в 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.
Запускаем проект для теста и вводим параметры общего ущерба (разбитые чашки, тарелки и т.п.)
Чтобы добавить выбора объема чаевых, вставляем расположенный ниже код в новую секцию 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):
Теперь при запуске приложения есть возможность добавить сумму счета, также работают кнопки «Добавить/Вычесть», но пока ничего не происходит.
Открываем 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
}
Теперь можно добавлять общий ущерб, чаевые и количество участников встречи. Ну и теперь самое главное…
Этот код подсчитывает затраты (#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.
Skillbox рекомендует:
- Двухлетний практический курс «Я — Веб-разработчик PRO» [4].
- Онлайн-курс «С#-разработчик» [5].
- Практический годовой курс «PHP-разработчик с 0 до PRO» [6].
Автор: fokus-lop
Источник [7]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/android/314996
Ссылки в тексте:
[1] «Мобильный разработчик PRO: https://skillbox.ru/agima/?utm_source=skillbox.media&utm_medium=habr.com&utm_campaign=AGIMA&utm_content=articles&utm_term=kotlintips
[2] загрузка основы проекта: https://github.com/lawreyios/tipcalculator/tree/starter_project
[3] инструмент material.io: https://material.io/tools/color/#!/?view.left=0&view.right=0&primary.color=37474F
[4] «Я — Веб-разработчик PRO»: https://iamwebdev.skillbox.ru/?utm_source=skillbox.media&utm_medium=habr.com&utm_campaign=WEBDEVPRO&utm_content=articles&utm_term=kotlintips
[5] «С#-разработчик»: https://skillbox.ru/c-sharp/?utm_source=skillbox.media&utm_medium=habr.com&utm_campaign=CSHDEV&utm_content=articles&utm_term=kotlintips
[6] «PHP-разработчик с 0 до PRO»: https://skillbox.ru/php/?utm_source=skillbox.media&utm_medium=habr.com&utm_campaign=PHPDEV&utm_content=articles&utm_term=kotlintips
[7] Источник: https://habr.com/ru/post/448582/?utm_campaign=448582
Нажмите здесь для печати.