The following app basically sums up the costs for an evening and calculates the costs per person. The user can input the description of the costs [String] (for example, round one = Spare Ribs Place, round two = Beer Place, etc.), the costs of the round [Double] (for example, 50$, 10.15$, etc.) and the amount of people who participated [Int].
The description of the costs and the costs are being taken via an Alertdialog after having pressed the FAB.
After pressing "Calculate" the total sum is divided by the amount of people and displayed in a textview.
I know I have still a long way to go but I am willing to learn and therefore more than thankful for any advice in any respect.
MAIN ACTIVITY.KT
package com.hooni.nbun1kotlin
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.alertdialog_addvalue.view.*
import kotlinx.android.synthetic.main.toolbar.*
class MainActivity : AppCompatActivity() {
// Declaring member variables:
// - mutableList contains data class Entry (Name of Entry, Value of Entry)
// - sumValue is the sum of the values of all entries
private val entryList: MutableList<Entry> = mutableListOf()
private var sumValue: Double = 0.0
private lateinit var textViewTotalValue: TextView
private lateinit var textViewValuePerPerson: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initUI()
}
private fun initUI() {
initToolbar()
initRecyclerView()
initFAB()
initButtons()
initSumFields()
}
private fun initRecyclerView() {
recyclerView_ListOfItems.apply {
layoutManager = LinearLayoutManager(this@MainActivity)
adapter = ItemAdapter(entryList)
}
}
private fun initToolbar() {
toolbar.inflateMenu(R.menu.menu_main)
toolbar.setOnMenuItemClickListener {
when(it.itemId) {
R.id.settings -> Toast.makeText(this, "Settings", Toast.LENGTH_SHORT).show()
R.id.share -> Toast.makeText(this, "Share", Toast.LENGTH_SHORT).show()
}
true
}
}
private fun initFAB() {
val fab: View = findViewById(R.id.fab)
fab.setOnClickListener {
val mDialogView = LayoutInflater.from(this).inflate(R.layout.alertdialog_addvalue,null)
val mBuilder = AlertDialog.Builder(this).setView(mDialogView).setTitle("Add Entry")
val mAlertDialog = mBuilder.show()
// Action when pressing "Cancel" in the popup
mDialogView.button_cancel.setOnClickListener {
mAlertDialog.dismiss()
}
// If "OK" is being pressed the values from the edit text field (Name & Value of the entry)
// are converted to the corresponding data types (String, Double) and then added to the
// list of entries (entryList)
//
// The adapter is being notified that there has been a change in the mutableList
// the sumValue (Double) is being increased by the entered value and the textView
// is being updated
mDialogView.button_ok.setOnClickListener {
mAlertDialog.dismiss()
val itemName = mDialogView.editText_itemName.text.toString()
val itemValue = mDialogView.editText_itemValue.text.toString().toDouble()
entryList.add(Entry(itemName,itemValue))
recyclerView_ListOfItems.adapter?.notifyDataSetChanged()
sumValue += itemValue
textViewTotalValue.text = sumValue.toString()
// A snackbar is being shown to undo the action (i.e. removing the entry from the
// mutableList (entryList), updating sumValue (Double) & the corresponding textView
val snackbar = Snackbar.make(mainActivity,"Item added",Snackbar.LENGTH_SHORT)
snackbar.setAction("Undo") {
entryList.remove(Entry(itemName,itemValue))
recyclerView_ListOfItems.adapter?.notifyDataSetChanged()
sumValue -= itemValue
textViewTotalValue.text = sumValue.toString()
}
snackbar.show()
}
}
}
private fun initButtons() {
// the UI for increasing the amount of people & calculate button are initialized
val buttonIncrease = findViewById<Button>(R.id.button_increasePeople)
val buttonDecrease = findViewById<Button>(R.id.button_decreasePeople)
val editTextAmountOfPeople = findViewById<TextView>(R.id.textView_amountOfPeople)
val buttonCalculate = findViewById<Button>(R.id.button_calculate)
// the textView displaying the amount of People is set to "2"
editTextAmountOfPeople.text = "2"
// OnClickListener for increasing/decreasing amount of People & Calculating are set
buttonIncrease.setOnClickListener {
if(editTextAmountOfPeople.text.toString().toInt() < 10) editTextAmountOfPeople.text = (editTextAmountOfPeople.text.toString().toInt() + 1).toString()
else (Toast.makeText(this@MainActivity,"10 People Maximum",Toast.LENGTH_SHORT)).show()
}
buttonDecrease.setOnClickListener {
if(editTextAmountOfPeople.text.toString().toInt() > 2) editTextAmountOfPeople.text = (editTextAmountOfPeople.text.toString().toInt() - 1).toString()
else (Toast.makeText(this@MainActivity,"2 People Minimum",Toast.LENGTH_SHORT)).show()
}
buttonCalculate.setOnClickListener {
val valuePerPerson = sumValue / editTextAmountOfPeople.text.toString().toDouble()
textViewValuePerPerson.text = valuePerPerson.toString()
}
}
private fun initSumFields() {
textViewTotalValue = findViewById(R.id.textView_totalValue)
textViewValuePerPerson = findViewById(R.id.textView_valuePerPerson)
}
// Entry containing the name and the value
data class Entry(var name: String, var value: Double)
}
ITEMADAPTER.KT
package com.hooni.nbun1kotlin
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.listview_item.view.*
class ItemAdapter (private val items: MutableList<MainActivity.Entry>) :
RecyclerView.Adapter<ItemAdapter.ItemViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
return ItemViewHolder(LayoutInflater.from(parent.context)
.inflate(R.layout.listview_item,parent,false))
}
override fun getItemCount(): Int {
return items.size
}
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
when(holder) {
is ItemViewHolder -> {
holder?.itemDescription?.text = items.get(position).name
holder?.itemValue?.text = items.get(position).value.toString()
}
}
}
class ItemViewHolder constructor(view: View) : RecyclerView.ViewHolder (view) {
val itemDescription = view.listView_valueDescription!!
val itemValue = view.listView_value!!
}
}
ACTIVITY_MAIN.XML
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/mainActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<include
layout="@layout/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:layout_marginBottom="8dp"
android:src="@mipmap/fab_add"
app:layout_constraintBottom_toTopOf="@id/linearLayout_BottomBar"
app:layout_constraintRight_toRightOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView_ListOfItems"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/linearLayout_BottomBar">
</androidx.recyclerview.widget.RecyclerView>
<LinearLayout
android:id="@+id/linearLayout_BottomBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="@+id/button_decreasePeople"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-" />
<TextView
android:id="@+id/textView_amountOfPeople"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2" />
<Button
android:id="@+id/button_increasePeople"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+" />
</LinearLayout>
<Button
android:id="@+id/button_calculate"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Calculate" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar">
<TextView
android:id="@+id/textView_valuePerPerson"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
tools:text="50000" />
<TextView
android:id="@+id/textView_totalValue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
tools:text="100000" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
ALERTDIALOG_ADDVALUE.XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/editText_itemName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="text"
android:hint="Enter Description"/>
<EditText
android:id="@+id/editText_itemValue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="numberDecimal"
android:hint="Enter Value"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/button_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@android:string/cancel" />
<Button
android:id="@+id/button_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@android:string/ok" />
</LinearLayout>
</LinearLayout>
LISTVIEW_ITEM.XML
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 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="wrap_content"
android:layout_margin="4dp"
app:cardElevation="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/listView_valueDescription"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_weight="2"
android:gravity="center_vertical|start"
android:textSize="24sp"
tools:text='맛있는 식당"'>
</TextView>
<TextView
android:id="@+id/listView_value"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="4"
android:gravity="center"
android:textSize="24sp"
tools:text="60,000">
</TextView>
</LinearLayout>
</androidx.cardview.widget.CardView>
TOOLBAR.XML
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar 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:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
android:background="@color/colorPrimary"
android:elevation="4dp"
app:title="Toolbar"
tools:menu="@menu/menu_main"
/>
MENU_MAIN.XML
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/share"
android:icon="@android:drawable/ic_menu_share"
android:title="@string/action_share"
app:showAsAction="always"></item>
<item
android:id="@+id/settings"
android:icon="@android:drawable/ic_menu_preferences"
android:title="@string/action_settings"></item>
</menu>