Reputation: 99
In classic Android programming (before composites) to show list on recyclerview I need adapter and if I want to give any action like clickable element, where logic will be provide in fragment/viewmodel I had to through argument create such parameter like
(Int) -> Unit
how does it look in jetpack compose when I create lazy column? Should it look the same and just create paramaters in Screens/UI
then configure logic in the same way in fragment/viewmodel or there is some other approachs?
Upvotes: 0
Views: 1140
Reputation: 2565
Getting rid of all the bloat of recyclerview is one of my favorite advantages of compose. Let's assume you'd like to include the following list in your screen:
@Composable
private fun TestList(
myItems: List<String>,
onClick: (String) -> Unit,
modifier: Modifier = Modifier,
) {
LazyColumn(modifier.fillMaxSize()) {
items(myItems) { item ->
TestItemView(
text = item,
onClick = onClick
)
}
}
}
@Composable
private fun TestItemView(
text: String,
onClick: (String) -> Unit,
modifier: Modifier = Modifier,
) {
Surface(modifier.fillMaxWidth()) {
Button(
onClick = { onClick(text) },
content = { Text(text) }
)
}
}
Option A: keep the state in the composable.
@Composable
private fun TestScreenA() {
val myItems = remember { mutableStateOf(listOf("A", "B", "C", "D")) }
TestList(
myItems = myItems.value,
onClick = { clickedItem ->
// for demonstration purposes we remove item on click
myItems.value = myItems.value.filterNot { it == clickedItem }
}
)
}
Option B: Keep the state in the viewmodel (like before)
class TestViewModelB: ViewModel() {
private val _myItems = MutableStateFlow(listOf("A", "B", "C", "D"))
val myItems = _myItems.asStateFlow()
fun onItemClicked(clickedItem: String){
// for demonstration purposes we remove item on click
_myItems.update { items -> items.filterNot { it == clickedItem } }
}
}
@Composable
private fun TestScreenB(
// inject viewModel here using your favorite DI-Framework
viewModel: TestViewModelB
) {
TestList(
// you might want to use collectAsStateWithLifecycle in the future
// see https://medium.com/androiddevelopers/consuming-flows-safely-in-jetpack-compose-cde014d0d5a3
myItems = viewModel.myItems.collectAsState().value,
onClick = viewModel::onItemClicked
)
}
Both options are viable (especially when using rememberSavable
).
However, i suggest to use optionB for people just migrating to compose, as its more similar to what they're used. I personally use OptionA for simple states, and OptionB for more complex ones (like a list)
Upvotes: 1