0
0
Android Kotlinmobile~20 mins

MVVM pattern in Android Kotlin - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Simple Counter MVVM
A screen that shows a number and a button to increase it using MVVM pattern.
Target UI
-------------------
|   Simple Counter  |
|                   |
|       0           |
|                   |
|   [ Increase ]    |
-------------------
Use MVVM architecture with ViewModel and LiveData
Display a number starting at 0
Increase number by 1 when button is clicked
Update UI automatically when number changes
Starter Code
Android Kotlin
package com.example.mvvmcounter

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.viewModels
import androidx.lifecycle.Observer
import com.example.mvvmcounter.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private val viewModel: CounterViewModel by viewModels()

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

        // TODO: Observe LiveData from ViewModel and update UI

        // TODO: Set button click listener to increase counter
    }
}

// TODO: Create CounterViewModel class with LiveData and increase function
Task 1
Task 2
Task 3
Task 4
Solution
Android Kotlin
package com.example.mvvmcounter

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.viewModels
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel
import com.example.mvvmcounter.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private val viewModel: CounterViewModel by viewModels()

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

        viewModel.counter.observe(this, Observer { count ->
            binding.textViewCounter.text = count.toString()
        })

        binding.buttonIncrease.setOnClickListener {
            viewModel.increaseCounter()
        }
    }
}

class CounterViewModel : ViewModel() {
    private val _counter = MutableLiveData(0)
    val counter: LiveData<Int> = _counter

    fun increaseCounter() {
        _counter.value = (_counter.value ?: 0) + 1
    }
}

This solution uses the MVVM pattern by separating UI logic and data logic.

The CounterViewModel holds the counter data as LiveData. It starts at 0 and has a method to increase the count.

The MainActivity observes the LiveData from the ViewModel. When the counter changes, the UI text updates automatically.

The button click calls the ViewModel's increase method, keeping UI and data separate and reactive.

Final Result
Completed Screen
-------------------
|   Simple Counter  |
|                   |
|       0           |
|                   |
|   [ Increase ]    |
-------------------
When user taps 'Increase' button, the number increments by 1
The displayed number updates immediately without manual UI refresh
Stretch Goal
Add a Reset button that sets the counter back to 0
💡 Hint
Add another button in the layout and a resetCounter() method in ViewModel that sets MutableLiveData to 0