All days
Day 08Module 4 · Architecture Components· 4–6 hrs

Architecture II — Data Binding, MVVM, LiveData, Safe Args

Finish the BMI Calculator using MVVM: ViewModel holds state, LiveData notifies the UI, Data Binding removes findViewById, and Safe Args replaces Bundle string keys.

0% done

Key concepts

  • MVVM separation (View / ViewModel / Model)
  • ViewModel survives configuration changes
  • LiveData & observe
  • Data Binding (<layout> tag)
  • Safe Args plugin

Lectures in this day

  1. 01

    Introducing Data Binding

    Data Binding lets your XML layout know about your Kotlin values directly, so you don't have to write `findViewById` for every view. After you turn it on in Gradle, Android Studio makes a typed `Binding` class from your layout.

    Real life · A voice-controlled remote: instead of hunting for the right button, you just say the name of the thing you want.
    gradle
    // build.gradle (Module: app)
    android {
      buildFeatures { dataBinding = true }   // turn it on
    }

    Practice · 3 quick questions

    1. Q1.Data Binding lets you…

    2. Q2.It's enabled in…

    3. Q3.Layouts using it start with…

    Pick one answer per question.
  2. 02

    Introducing MVVM and ViewModel

    MVVM is a way to organize your code into 3 layers. Model = your data. View = the screen you see. ViewModel = the brain that holds the state and does the logic. The ViewModel survives when you rotate the phone, so nothing is lost.

    Real life · In a restaurant, waiters (screens) change shifts, but the chef's prep station (ViewModel) stays the same all day.
    kotlin
    class BmiViewModel : ViewModel() {
        var bmi: Float = 0f
            private set                              0
    
        fun calculate(heightCm: Float, weightKg: Float) {
            val m = heightCm / 100                   1
            bmi = weightKg / (m * m)                 2
        }
    }

    Practice · 3 quick questions

    1. Q1.MVVM stands for…

    2. Q2.ViewModel survives…

    3. Q3.ViewModel should NOT hold…

    Pick one answer per question.
  3. 03

    Apply MVVM to BMI Calculator App

    Move the BMI math out of the Fragment (the screen) and into the BmiViewModel (the brain). The screen only reads the numbers the user typed and asks the ViewModel to compute — the screen has no math left.

    Real life · A cashier just types the items; the cash register (ViewModel) does the math. Swap cashiers — the register keeps working.
    kotlin
    class ResultFragment : Fragment(R.layout.fragment_result) {
        0
        private val vm: BmiViewModel by activityViewModels()
    
        override fun onViewCreated(v: View, s: Bundle?) {
            val h = arguments?.getFloat("heightCm") ?: 0f
            val w = arguments?.getFloat("weightKg") ?: 0f
            vm.calculate(h, w)
            v.findViewById<TextView>(R.id.result).text =
                "BMI = %.1f".format(vm.bmi)
        }
    }

    Practice · 3 quick questions

    1. Q1.For BMI MVVM, the calculation lives in…

    2. Q2.UI observes…

    3. Q3.Height/weight EditText values become…

    Pick one answer per question.
  4. 04

    Live Data

    LiveData is a special box you can watch. When the value inside changes, the screens watching it are told to update. Best of all, LiveData knows the screen's life cycle — it stops sending updates when the screen is gone, so nothing leaks.

    Real life · A newspaper subscription that pauses on its own when you leave town — no pile of papers at the door.
    kotlin
    class BmiViewModel : ViewModel() {
        0
        private val _bmi = MutableLiveData<Float>()
        val bmi: LiveData<Float> = _bmi
    
        fun calculate(h: Float, w: Float) {
            val m = h / 100
            _bmi.value = w / (m * m)              1
        }
    }
    
    2
    vm.bmi.observe(viewLifecycleOwner) { value ->
        binding.result.text = "BMI = %.1f".format(value)
    }

    Practice · 3 quick questions

    1. Q1.LiveData is…

    2. Q2.You update value with…

    3. Q3.Observers are added with…

    Pick one answer per question.
  5. 05

    Argument Passing using Safe Args

    Safe Args is a Gradle plugin that writes typed helper classes for you. Instead of guessing string keys and casting types, you call a generated function that already knows what each argument is.

    Real life · Instead of scribbling notes on scrap paper, you fill in a real form — the fields are labeled and typed.
    xml
    <!-- nav_graph.xml -->
    <class="tok-key">action android:id="@+id/toResult" app:destination="@id/resultFragment">
        <class="tok-key">argument android:name="heightCm" app:argType="float" />
        <class="tok-key">argument android:name="weightKg" app:argType="float" />
    </class="tok-key">action>
    
    <!-- In the fragment (Kotlin): -->
    <!-- val action = InputFragmentDirections.toResult(h, w)     -->
    <!-- findNavController().navigate(action)                    -->

    Practice · 3 quick questions

    1. Q1.Safe Args is a…

    2. Q2.The main benefit is…

    3. Q3.You declare args in…

    Pick one answer per question.
  6. 06

    Module 4 Wrap-up / Summary

    You can now split screens into Fragments, connect them safely with Navigation + Safe Args, and keep state cleanly in a ViewModel that watches over LiveData.

    Real life · You've upgraded from a shack to a proper flat with labeled doors, wiring diagrams, and a fuse box.

    Practice · 3 quick questions

    1. Q1.Module 4 mostly covered…

    2. Q2.Which is NOT Module 4?

    3. Q3.Now you can build…

    Pick one answer per question.

Real-life analogies

ViewModel

A chef's prep station in the kitchen. Waiters (Activities) change shifts (rotate), but the prep station stays and keeps the food ready.

LiveData

A notification bell — anyone subscribed gets pinged when data changes. When they leave the screen, they auto-unsubscribe.

Code examples

ViewModel + LiveData

kotlin
class BmiViewModel : ViewModel() {
    private val _bmi = MutableLiveData<Float>()
    val bmi: LiveData<Float> = _bmi

    fun calculate(heightM: Float, weightKg: Float) {
        _bmi.value = weightKg / (heightM * heightM)
    }
}

0
val vm: BmiViewModel by viewModels()
vm.bmi.observe(viewLifecycleOwner) { value ->
    binding.resultText.text = "BMI: %.1f".format(value)
}

Data binding layout

xml
<class="tok-key">layout xmlns:android="http://schemas.android.com/apk/res/android">
    <class="tok-key">data>
        <class="tok-key">variable name="vm" type="com.example.bmi.BmiViewModel" />
    </class="tok-key">data>
    <class="tok-key">LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <class="tok-key">TextView android:text="@{`BMI: ` + vm.bmi}"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content" />
    </class="tok-key">LinearLayout>
</class="tok-key">layout>

Hands-on checklist

Milestone

Fully functional BMI Calculator in clean MVVM.

Common pitfalls

  • Observing LiveData with `this` in a Fragment — use `viewLifecycleOwner`.
  • Holding an Activity/Context reference in ViewModel — memory leak.