I have a reusable layout containing a LazyColumn
and a button to scroll to the top of the LazyColumn
. What is the most efficient way to declare my button (and make sure the click event works) so that I don't have to decalre it every time I create a new screen?
@Composable
fun MyReusableScaffold(scaffoldTitle: String, scaffoldContent: @Composable () -> Unit) {
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
LargeTopAppBar(
title = { Text(text = scaffoldTitle) },
scrollBehavior = scrollBehavior
)
},
content = { contentPadding ->
scaffoldContent(contentPadding = contentPadding)
}
)
}
@Composable
fun MyScreen(navController: NavController) {
MyReusableScaffold(
scaffoldTitle = "Hello Android",
scaffoldContent = {
MyScreenContent(contentPadding = it)
}
)
}
@Composable
fun MyScreenContent(modifier: Modifier = Modifier,
contentPadding: PaddingValues = PaddingValues()) {
LazyColumn(
state = listState,
contentPadding = contentPadding,
) {
items(22) {
ListItem(it)
}
}
val showButton by remember {
derivedStateOf {
listState.firstVisibleItemIndex > 0
}
}
AnimatedVisibility(
visible = showButton,
enter = fadeIn(),
exit = fadeOut(),
modifier = Modifier.align(BottomCenter)
) {
ScrollToTopButton(onClick = {
coroutineScope.launch {
listState.animateScrollToItem(index = 0)
}
})
}
}
@Composable
fun ScrollToTopButton(onClick: () -> Unit) {
Box(
Modifier
.fillMaxSize()
) {
Button(
onClick = { onClick() }
) {
Text(text = stringResource(id = R.string.top))
}
}
}
CodePudding user response:
You can move all the logic inside the ScrollToTopButton
.
Something like:
@Composable
fun ScrollToTopButton(
modifier : Modifier = Modifier,
listState : LazyListState) {
val coroutineScope = rememberCoroutineScope()
val showButton by remember {
derivedStateOf {
listState.firstVisibleItemIndex > 0
}
}
AnimatedVisibility(
visible = showButton,
enter = fadeIn(),
exit = fadeOut(),
) {
Box(
modifier
) {
Button(
onClick = {
coroutineScope.launch {
listState.animateScrollToItem(index = 0)
}
}
) {
Text(text = "Top")
}
}
}
}
and then use in all screens with:
val listState = rememberLazyListState()
LazyColumn(
state = listState,
contentPadding = contentPadding,
) {
items(100) {
androidx.compose.material.Text("" it)
}
}
ScrollToTopButton(
listState = listState
)