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

Дадаць каментар