Lesson 16: Passing Data Between Screens
Passing Data Between Screens
In lesson 15 we passed a simple taskId: Int between screens. That's actually the correct pattern — here's why, and how to use that ID to get the full object.
Why pass an ID, not the whole object
It's tempting to pass an entire Task object directly through navigation. Don't — routes need to be simple, serializable data (numbers, strings, booleans), and passing full objects through navigation args gets fragile fast once your data gets more complex. The standard pattern: pass the ID, then look up the full object on the destination screen.
Looking up the full task by ID
@Composable
fun TaskDetailScreen(taskId: Int, tasks: List) {
val task = tasks.find { it.id == taskId }
if (task != null) {
Column(modifier = Modifier.padding(24.dp)) {
Text(task.title, fontSize = 24.sp, fontWeight = FontWeight.Bold)
Text("Task #${task.id}")
}
} else {
Text("Task not found")
}
}Notice the if (task != null) check — this is Kotlin's null safety from lesson 4 in action. find returns null if nothing matches, and the compiler forces you to handle that case before using task.
Where does the tasks list actually come from?
Right now we've been hardcoding a local tasks list and passing it around screen to screen — workable for learning, but fragile: every screen needs the full list passed down, and there's no single source of truth. This is exactly the problem the next lesson solves.
Next: Lesson 17 — introducing ViewModel, so screens share data properly instead of passing it hand to hand.