I get a list of folders from the network and display it using tabs. How can I correctly redraw the tabs when I receive a new list? It may be a different size and with different folder names.
val selectedTabIndex = remember { mutableIntStateOf(0) }
val tabs =
listOf("Folder 1", "Folder 2", "Folder 3", "Folder 4", "Folder 5", "Folder 6", "Folder 7")
.toMutableStateList()
Row {
ScrollableTabRow(
selectedTabIndex = selectedTabIndex.intValue,
contentColor = Color.LightGray,
edgePadding = 0.dp
) {
tabs.forEachIndexed { tabIndex, tab ->
Tab(
selected = selectedTabIndex.intValue == tabIndex,
onClick = { selectedTabIndex.intValue = tabIndex },
text = { Text(text = tab) }
)
}
}
}
You declared tabs as follows:
val tabs = listOf("Folder 1", "Folder 2", "Folder 3").toMutableStateList()
This is equivalent to the more common syntax as follows:
val tabs = remember { mutableStateListOf("Folder 1", "Folder 2", "Folder 3") }
As a result, Jetpack Compose will properly observe the changes that happen to the tabs variable. Whenever you change the list by adding or removing an item, this will trigger a recomposition, and all Composables that depend on the tabs variable will be redrawn.
tabs.add("Folder 8")
As a result,
forEachIndexed
function will be re-executed andTab
Composables will be updated.However, you might want to make sure manually that selectedTabIndex
does not point to an invalid index. As of now, if you remove items from the tabs
list, it could happen that no Tab
is selected anymore. You can try it as follows:
val tabs = ...
// use "by" keyword to directly access the value property
var selectedTabIndex by remember { mutableStateOf(0) }
// at every Recomposition, we make sure that the selectedTabIndex is in range
selectedTabIndex = selectedTabIndex.coerceIn(0, tabs.size - 1)
A small side note, once you add some content to the tabs, you might will need to use the key
function to properly preserve the state when adding or removing tabs.