Створення калькулятора чайових на 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

Додати коментар або відгук