Week 4 Class 1 & 2

MVVM + Fragments Data Sending

Goals for today

  1. App Lifecycle -> Done
  2. Why MVVM? Intro to Data Persistence and data Loss without View Model? -> Done
  3. How to pass data between pages? Ft. Fragments -> done
  4. Application Context vs Context -> done
  5. Observer Pattern -> done
  6. Lamdas -> Sunday
  7. Interfaces -> Sunday
  8.  Next Class: App2 (Creating & Using ChatGPT API)

 

Bug Bounty

Rs. 1000 ($15) award when you find an issue that we struggle during class

App Building

1. Figma Design

2. Choosing a design pattern - > Declarative vs Imperative 

3. Build 

4. Test

Important Rule

Never spend more time on Framework

Copy Paste Framework -> Learn Logic 

Concept: Mutable vs Immutables?

// Mutable list (ArrayList)
val mutableList = mutableListOf(1, 2, 3)
mutableList[0] = 4  // Modifying an element
mutableList.add(5)  // Adding an element

// Immutable list (List)
val immutableList = listOf(1, 2, 3)
// The following line would not compile since the list is immutable
// immutableList[0] = 4
val vs var

App Lifecycles

App with lifecycles

Activity Lifecycle

Source:

https://developer.android.com/guide/components/activities/activity-lifecycle

Fragment Lifecycle

What are Fragments and why use them?

1. Reusability

2. Handling Configuration Changes: e.g. rotation

3. Responsive UI

(Most importantly Recommended by Android)

Important Rule

Spend less time on Framework more logic

e.g. Don't re-invent the wheel all the time

What is context?

Toast.maketext(context:this, "Hello World")

What is Top Bar?

What is a Design Pattern?

Help us follow rules -> Maintainable code

e.g. Singleton -> 

Life without Design Pattern: MVVM

MVVM Benefits:

1. State Persistence -> Data is not lost but saved in Memory

2. Separation of concerns (Business Logic is Separate)

3. Testability

ViewModel

  • Solves the problem of persisting data
  • helps creating threads for Async calls / Network calls
  • Separate lifecycle which lives beyond activity

ViewModel LifeCycle

Observer Pattern

ViewModel is stored in RAM until

ViewModel

Rules

1. ViewModel shouldn't access View directly

2. One to many relationship, anyone can access ViewModel and observe it's data

3. Know how to pass context

Creating ViewModel

Official Source: https://developer.android.com/guide/fragments/communicate
Sharing Data between Fragments

Observer Pattern

YouTube channel analogy

 

LiveData -> Observable -> YouTube channel

inside Fragment/ Activites -> Observer -> You (who subscribed)

.observe means subscribing (only who subscribe get to see)

 

 

by activityViewModels()

scope of activity

passing data between fragments

by ViewModels()

not passing data

Interfaces

Vehicle Class

Car   

Aeroplane

rules to give to class

Interface vs Class

Feature Classes Interfaces
Method Implementation Can have method implementations Only method signatures, no implementations
Inheritance Single inheritance (extends one class) Multiple inheritance (implements multiple interfaces)
Usage Defines objects, properties, and behavior Defines contracts for behavior
Abstraction Abstraction of data and behavior Higher level of abstraction, contract for behavior
Multiple Inheritance Not supported Supported (through implementing multiple interfaces)
Example class MyClass { ... } interface MyInterface { ... }

Lamda vs Interfaces

val multiply: (Int, Int) -> Int = { a, b -> a * b }

fun main() {
    val result = multiply(2, 3)
    println("Result: $result") // Output: Result: 6
}
interface Operation {
    fun perform(a: Int, b: Int): Int
}

class Multiply : Operation {
    override fun perform(a: Int, b: Int) = a * b
}

fun calculate(op: Operation, a: Int, b: Int): Int {
    return op.perform(a, b)
}

fun main() {
    val multiplyOp = Multiply()
    val result = calculate(multiplyOp, 2, 3)
    println("Result: $result") // Output: Result: 6
}

Simple Lamda Example

typealias Callback = (String) -> Unit

fun performTask(callback: Callback) {
    // Simulating some task
    val result = "Task completed successfully"
    callback(result)
}

fun main() {
    performTask { result ->
        println("Callback received: $result")
    }
}
import java.util.function.Consumer;

interface Callback {
    void onComplete(String result);
}

class Task {
    void performTask(Callback callback) {
        // Simulating some task
        String result = "Task completed successfully";
        callback.onComplete(result);
    }
}

public class Main {
    public static void main(String[] args) {
        Task task = new Task();
        task.performTask(result -> System.out.println("Callback received: " + result));
    }
}

without Lamda

public class Main {
    public static void main(String[] args) {
        Adder adder = new Adder();
        int result = adder.add(5, 7);
        System.out.println("Result of adding 5 and 7 is: " + result);
    }
}

class Adder {
    public int add(int a, int b) {
        return a + b;
    }
}
fun main() {
    val add: (Int, Int) -> Int = { a, b -> a + b }

    val result = add(5, 7)
    println("Result of adding 5 and 7 is: $result")
}

with Lamda in Kotlin

Trick of the Day

Made with Slides.com