Compose is stable, it's time to integrate it into our apps! But it can be harder than expected and there are some questions to answer. Can the same architecture of a View-based app be reused or should we change it? Should the Compose code be aware of the architecture at all? And should the non UI code be changed to start using Compose? What can be replaced with a Composable, only the layouts or also something else?
Probably the best answer to all these questions is “it depends”, in this talk we’ll see some reasons and how to leverage Compose and the other tools to create a good architecture. Compose is more than just a UI framework and it can seem appealing to use it in a big portion of an app, a good architecture can be useful to limit this portion and use it only when necessary.
34. data class Note(
val id: Int,
val title: String,
var checked: Boolean
)_
Notes(
state = state,
onCheckedChange = { noteToToggle
-
>
state = state.copy(
notes = state.notes
.map { note
-
>
if (note.id
=
=
noteToToggle.id) {
note.copy(checked = !note.checked)
} else {
note
}
}
)
}
)
35. data class Note(
val id: Int,
val title: String,
var checked: Boolean
)
Notes(
state = state,
onCheckedChange = { noteToToggle
-
>
noteToToggle.checked = !noteToToggle.checked
}
)
Not
so
easy…
40. data class Note(
val id: Int,
val title: String,
var checked: Boolean
)
Notes(
state = state,
onCheckedChange = { noteToToggle
-
>
noteToToggle.checked = !noteToToggle.checked
}
)
41. data class Note(
val id: Int,
val title: String,
) {
var checked: Boolean by mutableStateOf(false)
}
Notes(
state = state,
onCheckedChange = { noteToToggle
-
>
noteToToggle.checked = !noteToToggle.checked
}
)
66. @Composable
inline fun <reified T : Any> rememberSingletonEntryPoint(): T {
val context = LocalContext.current
return remember {
EntryPointAccessors.fromApplication(context, T
:
:
class.java)
}
}
89. @HiltViewModel
class DetailViewModel @Inject constructor(
private val myUseCase: MyUseCase,
savedStateHandle: SavedStateHandle
) : ViewModel() {
init {
val id = savedStateHandle.get<Int>("id")
}
}_
90. @HiltViewModel
class DetailViewModel @Inject constructor(
private val myUseCase: MyUseCase,
savedStateHandle: SavedStateHandle
) : ViewModel() {
init {
val id = savedStateHandle.get<Int>("id")
viewModelScope.launch {
myUseCase.suspendMethod(id)
}
}
}_
91. @HiltViewModel
class DetailViewModel @Inject constructor(
private val myUseCase: MyUseCase,
savedStateHandle: SavedStateHandle
) : ViewModel() {
var state by mutableStateOf("")
private set
init {
val id = savedStateHandle.get<Int>("id")
viewModelScope.launch {
state = myUseCase.suspendMethod(id)
}
}
}_
95. @Composable
fun DetailScreen() {
val viewModel = hiltViewModel<DetailViewModel>()
val stateConnectedToViewModelLifecycle = viewModel.state
val remembered = remember {
"executed again on configuration change and when navigating back"
}
}_
96. @Composable
fun DetailScreen() {
val viewModel = hiltViewModel<DetailViewModel>()
val stateConnectedToViewModelLifecycle = viewModel.state
val remembered = remember {
"executed again on configuration change and when navigating back"
}
val saveable = rememberSaveable {
"saved in a bundle"
}
}_
97. @Composable
fun DetailScreen() {
val viewModel = hiltViewModel<DetailViewModel>()
val stateConnectedToViewModelLifecycle = viewModel.state
val remembered = remember {
"executed again on configuration change and when navigating back"
}
val saveable = rememberSaveable {
"saved in a bundle"
}
LaunchedEffect(Unit) {
/
/
executed again on configuration change and when navigating back
}
}_
103. Links
&
contacts
Architecting your Compose UI
developer.android.com/jetpack/compose/architecture
Jose Alcérreca - LiveData with SnackBar, Navigation and other events (the SingleLiveEvent case)
medium.com/androiddevelopers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150
Michael Ferguson - Android SingleLiveEvent Redux with Kotlin Flow
proandroiddev.com/android-singleliveevent-redux-with-kotlin-flow-b755c70bb055
Lifecycle of composables
developer.android.com/jetpack/compose/lifecycle
Manuel Vivo - A Compose state of mind: Using Jetpack Compose's automatic state observation
www.youtube.com/watch?v=rmv2ug-wW4U
Fabio Collini - ViewModels using Compose: MutableStateFlows or MutableStates?
proandroiddev.com/viewmodels-using-compose-mutablestateflows-or-mutablestates-64d34ba548c5
@fabioCollini
linkedin.com/in/fabiocollini
github.com/fabioCollini
medium.com/@fabioCollini