Tip Calculator App in Android Studio Using Kotlin

Hello Developers, welcome to Techpass Master, In this post, you will learn How to build a Tip Calculator app in Android Studio Using Kotlin. We have also created a complete series of this project on Youtube, you can get it in my Youtube channel. In this post, I will share complete source code of the app.

Tip Calculator App in Android Studio Using Kotlin
Tip Calculator App in Android Studio Using Kotlin

If you are a beginner, so I will suggest you watch all videos of this app series for better understanding, below, I will put all videos of this app series . If you really want to learn, how to build basic calculation-related things that are worked in App, so watch all videos and don’t copy and paste,

Below, I have shared the source code of the tip calculator app using Kotlin step-by-step. So without any further discussion let’s get started!

Tip Calculator App in Android Studio Using Kotlin (Complete Code)

activity_main.xml (UI Design)

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/black"
    tools:context=".MainActivity">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp">

        <TextView
            android:id="@+id/tvTitle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="Basic Tip Calculator"
            android:textColor="@color/white"
            android:textSize="32sp"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <EditText
            android:id="@+id/edtBill"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:gravity="center"
            android:hint="Enter your bill amount"
            android:inputType="numberDecimal"
            android:textColor="@color/white"
            android:textColorHint="@color/white"
            android:textSize="22sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/tvTitle" />

        <TextView
            android:id="@+id/tvTipPercentageTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="22dp"
            android:text="How was the service (Tip %)"
            android:textColor="#DCEDA2"
            android:textSize="20sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/edtBill" />

        <RadioGroup
            android:id="@+id/rgTipOptions"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:checkedButton="@id/rbTipTwentyPercent"
            android:orientation="vertical"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tvTipPercentageTitle">

            <RadioButton
                android:id="@+id/rbTipTwentyPercent"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Amazing (20%)"
                android:textSize="16sp"
                android:textColor="@color/white" />

            <RadioButton
                android:id="@+id/rbTipFifteenPercent"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Good (15%)"
                android:textSize="16sp"
                android:textColor="@color/white" />

            <RadioButton
                android:id="@+id/rbTipTanPercent"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Ok (10%)"
                android:textSize="16sp"
                android:textColor="@color/white" />
        </RadioGroup>

        <TextView
            android:id="@+id/tvNumberOfPerson"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:text="Number of Person"
            android:textAllCaps="false"
            android:textColor="#DCEDA2"
            android:textSize="18sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/rgTipOptions" />

        <Button
            android:id="@+id/btnPersonPlus"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:backgroundTint="#FAFAFA"
            android:text="+"
            android:textColor="#E80808"
            android:textSize="18sp"
            app:layout_constraintStart_toStartOf="@id/tvNumberOfPerson"
            app:layout_constraintTop_toBottomOf="@id/tvNumberOfPerson" />

        <Button
            android:id="@+id/btnPersonMinus"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:backgroundTint="#FAFAFA"
            android:text="-"
            android:textColor="#E80808"
            android:textSize="18sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tvNumberOfPerson" />

        <TextView
            android:id="@+id/tvPersonCount"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="1"
            android:textColor="@color/white"
            android:textSize="20sp"
            app:layout_constraintBottom_toBottomOf="@+id/btnPersonPlus"
            app:layout_constraintEnd_toStartOf="@+id/btnPersonMinus"
            app:layout_constraintStart_toEndOf="@+id/btnPersonPlus"
            app:layout_constraintTop_toTopOf="@+id/btnPersonPlus" />

        <Button
            android:id="@+id/btnCalculateTip"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:backgroundTint="#FAFAFA"
            android:text="calculate"
            android:textColor="#E80808"
            android:textSize="16sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/btnPersonMinus" />

        <TextView
            android:id="@+id/tvTotalTip"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:textColor="@color/white"
            android:textStyle="bold"
            android:textSize="18sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@id/btnCalculateTip" />

        <TextView
            android:id="@+id/tvTipPerPerson"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:textColor="@color/white"
            android:textStyle="bold"
            android:textSize="18sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/tvTotalBillPlusTip" />

        <TextView
            android:id="@+id/tvTotalBillPlusTip"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:textColor="@color/white"
            android:textStyle="bold"
            android:textSize="18sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/tvTotalTip" />

        <TextView
            android:id="@+id/tvTotalPerPerson"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:textColor="@color/white"
            android:textStyle="bold"
            android:textSize="18sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/tvTipPerPerson" />

        <ImageView
            android:id="@+id/imgCopyTip"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginTop="24dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:src="@drawable/ic_copy"
            android:visibility="gone"
            app:layout_constraintEnd_toStartOf="@+id/guideline"
            app:layout_constraintTop_toBottomOf="@+id/tvTotalPerPerson"
            tools:ignore="ContentDescription" />

        <ImageView
            android:id="@+id/imgShareTip"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="24dp"
            android:src="@drawable/ic_share"
            android:visibility="gone"
            app:layout_constraintStart_toStartOf="@+id/guideline"
            app:layout_constraintTop_toBottomOf="@+id/tvTotalPerPerson"
            tools:ignore="ContentDescription" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.5" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>

MainActivity.kt (Main Logic)

package com.taiyabali.basictipcalculator

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Toast
import com.taiyabali.basictipcalculator.databinding.ActivityMainBinding
import java.text.NumberFormat
import java.util.*

/**
 * Created by Techpass Master.
 * Website - https://techpassmaster.com/
 * Email id - hello@techpassmaster.com
 */

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding
    private var countPerson = 1

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.edtBill.requestFocus()
        onViewClick()
    }

    private fun onViewClick() {

        with(binding) {
            btnCalculateTip.setOnClickListener {
                calculateTip()
            }

            btnPersonPlus.setOnClickListener {
                countPerson++
                tvPersonCount.text = countPerson.toString()
            }

            btnPersonMinus.setOnClickListener {
                if (countPerson > 1) {
                    countPerson--
                    tvPersonCount.text = countPerson.toString()
                }
            }

            imgCopyTip.setOnClickListener {
                val tipFormatted = "${tvTotalTip.text}\n" +
                        "${tvTotalBillPlusTip.text}\n" +
                        "${tvTipPerPerson.text}\n" +
                        "${tvTotalPerPerson.text}"

                copyTipResult(tipFormatted)
            }

            imgShareTip.setOnClickListener {
                val tipFormatted = "${tvTotalTip.text}\n" +
                        "${tvTotalBillPlusTip.text}\n" +
                        "${tvTipPerPerson.text}\n" +
                        "${tvTotalPerPerson.text}"

                shareTipResult(tipFormatted)
            }
        }
    }

    private fun calculateTip() {
            //      get bill cost from EditText.
            //      set total bill amount in the cost.
        val totalBill: String = binding.edtBill.text.toString()
        val cost = totalBill.toDoubleOrNull()

        if (totalBill.isNotEmpty()) {
            binding.imgCopyTip.visibility = View.VISIBLE
            binding.imgShareTip.visibility = View.VISIBLE

            //      get selected tip percentage
            val tipPercentage = when (binding.rgTipOptions.checkedRadioButtonId) {
                R.id.rbTipTwentyPercent -> 0.20
                R.id.rbTipFifteenPercent -> 0.15
                else -> 0.10
            }

            //      Calculate the tip according to percentage and set per person tip
            val tip = tipPercentage * cost!!
            showTotalTipResult(tip)

            //      Calculate & set the per person tip
            val perPersonTip = (tip / countPerson).toString()
            showPerPersonTipResult(perPersonTip.toDouble())

            //      Calculate & set total bill + tip
            val billPlusTip = cost.plus(tip)
            showTotalBillPlusTipResult(billPlusTip)

            //      Calculate & set per person total
            val totalPerPerson = (billPlusTip / countPerson).toString()
            showTotalPerPersonResult(totalPerPerson.toDouble())
        } else {
            Toast.makeText(this, "Please enter bill Amount", Toast.LENGTH_SHORT).show()
        }
    }

    private fun showTotalTipResult(tip: Double) {
        val numberFormat = NumberFormat.getCurrencyInstance(Locale("en", "in")).format(tip)
        binding.tvTotalTip.text = ("Total Tip: $numberFormat")
    }

    private fun showTotalBillPlusTipResult(tip: Double) {
        val numberFormat = NumberFormat.getCurrencyInstance(Locale("en", "in")).format(tip)
        binding.tvTotalBillPlusTip.text = ("Total Amount (Bill+Tip): $numberFormat")
    }

    private fun showPerPersonTipResult(tip: Double) {
        val numberFormat = NumberFormat.getCurrencyInstance(Locale("en", "in")).format(tip)
        binding.tvTipPerPerson.text = ("Per Person Tip: $numberFormat")

        if (countPerson == 1) {
            binding.tvTipPerPerson.text = ("Tip: $numberFormat")
        } else {
            binding.tvTipPerPerson.text = ("Per Person Tip: $numberFormat")
        }
    }

    private fun showTotalPerPersonResult(tip: Double) {
        val numberFormat = NumberFormat.getCurrencyInstance(Locale("en", "in")).format(tip)
        if (countPerson == 1) {
            binding.tvTotalPerPerson.text = ("Total: $numberFormat")
        } else {
            binding.tvTotalPerPerson.text = ("Total Per Person: $numberFormat")
        }
    }

    private fun copyTipResult(copyTipResultText : String){
        val clipboardManager = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
        val clipData = ClipData.newPlainText("text", copyTipResultText)
        clipboardManager.setPrimaryClip(clipData)
        Toast.makeText(this, "Tip copied", Toast.LENGTH_LONG).show()
    }

    private fun shareTipResult(shareTipResultText :String){
        val sendIntent: Intent = Intent().apply {
            action = Intent.ACTION_SEND
            putExtra(Intent.EXTRA_TEXT,shareTipResultText )
            type = "text/plain"
        }
        val shareIntent = Intent.createChooser(sendIntent, null)
        startActivity(shareIntent)
    }
}

Congratulations, all steps are done, now let’s run and test the application.

If you have any questions regarding this post. Feel free to comment and share the post with other developers.
Happy Learning 🙂

You May Also Like

Leave a Reply

Your email address will not be published. Required fields are marked *