Building a tip calculator in Kotlin: how does it work?

Building a tip calculator in Kotlin: how does it work?

We show you how to create a simple tip calculation application in Kotlin. To be more precise, Kotlin 1.3.21, Android 4, Android Studio 3. The article will be interesting, first of all, for those who start their journey in developing Android applications. It allows you to understand what and how works inside the application.

Such a calculator is useful when you need to calculate the amount of tips from a company that decides to spend time in a restaurant or cafe. Of course, not everyone and not always leaves tea for waiters, this is more of a Western tradition, but the process of developing such an application is interesting in any case.

We remind you: for all readers of "Habr" - a discount of 10 rubles when enrolling in any Skillbox course using the "Habr" promotional code.

Skillbox recommends: Practical course "Mobile Developer PRO.

Here's what the app looks like when it's running:

Building a tip calculator in Kotlin: how does it work?

You enter the desired percentage of the total amount, the number of participants in the meeting and get the result - the amount of tips that should be left.

Getting Started

The full interface of the app looks like this:
Building a tip calculator in Kotlin: how does it work?

Building a tip calculator in Kotlin: how does it work?

First action - project base download. Open it in Android Studio 3.0 or later. We build and run the project and see a white screen. Everything is fine, as it should be.

Building a tip calculator in Kotlin: how does it work?

Building a tip calculator in Kotlin: how does it work?

User actions are written in the project in chronological order, so that everything is clear. To view it, open View -> Tool Windows -> TODO.

We study the project and open colors.xml to evaluate the color palette. strings.xml contains text data (captions), and styles.xml contains several font templates.

Cost Section Development

Open activity_main.xml and add the code below to the 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"/>

Now you can style the values ​​directory or play with colors using material.io tool.

Now the project looks like this:

Building a tip calculator in Kotlin: how does it work?
As you can see, the cost calculation is based on the data entered by the user.

Development of the account section

Add the code below to the LinearLayout after the 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>

Close the LinearLayout after the TODOs list, and then add the new code, placing it inside the 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"/>

Since the main task of the application is to calculate the individual costs for each of the participants in the gatherings in the restaurant, the costPerPersonTextView plays the main role.

EditText limits input to one line, this parameter must be set to NumberDecimal inputType.

Building a tip calculator in Kotlin: how does it work?
We start the project for the test and enter the parameters of the total damage (broken cups, plates, etc.)

Development of the "People and Tips" section

To add a tip amount selector, paste the code below into a new LinearLayout section (#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>

This piece of code is required to accurately calculate the tip amount. The default text value is 20. ImageButtons are provided with icons in a folder with write permissions.

Copy the entire section and add the following (#5):

  • ImageButton ids (subtractPeopleButton, addPeopleButton)
  • TextView ids(numberOfPeopleStaticText, numberOfPeopleTextView)
  • DefaultText for numberOfPeopleTextView (should be 4).

Building a tip calculator in Kotlin: how does it work?

Now, when starting the application, it is possible to add the invoice amount, the Add / Subtract buttons also work, but so far nothing happens.

Add Views

Open MainActivity.kt and add this to the initViews function (#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
 
}

Finishing the buttons

To add support for button clicks, implement View.OnClickListener at the class level (#7):

class MainActivity: AppCompatActivity(), View.OnClickListener {

Compiling the project right now will not work, you need to perform a few more steps (# 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()
        }
    }

In terms of buttons and switches, Kotlin has everything organized very cool! Add the code below to all increment and decrement functions
(#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()
        }
    }

Here the code protects increment functions with maximum values ​​(MAX_TIP & MAX_PEOPLE). In addition, the code protects decrement functions with minimum values ​​(MIN_TIP & MIN_PEOPLE).

Now we bind the buttons to the listeners in the initViews function (#13):

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

Building a tip calculator in Kotlin: how does it work?

You can now add total damage, tips, and the number of meeting participants. Well, now the most important thing...

Cost section

This code calculates the costs (#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)
 
}

Well, here a function is called that makes it possible to take into account the number of people in the company and calculate the tip (#15):

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

We launch the application. It looks and works great. But it could be better.

If you try to remove the bill amount and then increase the number of hints or friends, the app will crash because there is no check for zero costs yet. Moreover, if you try to change the invoice amount, the charges will not be updated.

Final steps

Add TextWatcher (#16):

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

Then we embed the billEditText listener (#17):

billEditText.addTextChangedListener(this)

Plus add code to execute 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) {}

Building a tip calculator in Kotlin: how does it work?

Well, now everything works! Congratulations, you have written your own "Tipping Calculator" in Kotlin.

Building a tip calculator in Kotlin: how does it work?

Skillbox recommends:

Source: habr.com

Add a comment