Bryn Flow

🤖 Kotlin & Jetpack Compose Cheat Sheet

The syntax you look up over and over. Bookmark this page.

← Android Track

Variables & Functions

val name = "fixed"       // immutable
var count = 0             // mutable
val x: Int = 5             // explicit type

fun add(a: Int, b: Int): Int = a + b
fun greet(name: String = "there") = "Hi, $name"

// Lambda
val square: (Int) -> Int = { it * it }

Collections

val list = listOf(1, 2, 3)          // immutable
val mutable = mutableListOf(1, 2)
val map = mapOf("a" to 1, "b" to 2)

list.map { it * 2 }
list.filter { it > 1 }
list.forEach { println(it) }
list.firstOrNull { it > 5 }
list.sortedBy { it }

Null Safety

var name: String? = null    // nullable type
name?.length                 // safe call → null if name is null
name?.length ?: 0            // Elvis operator: default if null
name!!.length                // force unwrap (crashes if null)

if (name != null) {
    // smart-cast: name is String here
    println(name.length)
}

Classes & Data Classes

data class User(val id: Int, val name: String)
// auto: equals(), hashCode(), toString(), copy()

val u = User(1, "Ana")
val u2 = u.copy(name = "Ben")

sealed interface Result
data class Ok(val value: String) : Result
data class Err(val msg: String) : Result

when (result) {
    is Ok -> println(result.value)
    is Err -> println(result.msg)
}

Coroutines

viewModelScope.launch {
    val data = withContext(Dispatchers.IO) { api.getData() }
    _uiState.value = data
}

suspend fun loadUser(id: Int): User = api.getUser(id)

// Flow
val flow: Flow<Int> = flowOf(1, 2, 3)
flow.collect { println(it) }
flow.stateIn(scope, SharingStarted.WhileSubscribed(5000), initial)

Compose State

var count by remember { mutableStateOf(0) }

val vmState by viewModel.uiState.collectAsState()

// Derived state (recomputes only when inputs change)
val isValid by remember(email) { derivedStateOf { email.contains("@") } }

// Side effect on composition
LaunchedEffect(key1 = userId) {
    viewModel.load(userId)
}

Compose Layout

Column(Modifier.padding(16.dp)) { /* children stacked vertically */ }
Row(Modifier.fillMaxWidth()) { /* children in a row */ }
Box(Modifier.size(100.dp)) { /* stacked/overlapping */ }

Modifier
    .fillMaxWidth()
    .padding(12.dp)
    .background(Color.White)
    .clickable { /* handle tap */ }

Compose Lists

LazyColumn {
    items(list, key = { it.id }) { item ->
        Text(item.title)
    }
}

LazyRow { items(images) { img -> AsyncImage(img) } }

Room

@Entity data class Note(@PrimaryKey(autoGenerate = true) val id: Int = 0, val title: String)

@Dao interface NoteDao {
    @Query("SELECT * FROM Note") fun getAll(): Flow<List<Note>>
    @Insert suspend fun insert(note: Note)
    @Delete suspend fun delete(note: Note)
}

@Database(entities = [Note::class], version = 1)
abstract class AppDb : RoomDatabase() { abstract fun noteDao(): NoteDao }

Want the full explanations?

Every item here is covered in depth on the Android track.

Back to Android Track