GvH*_*ish 7 android android-layout android-jetpack android-jetpack-compose
如何在 Jetpack Compose 中使用事务执行此滚动隐藏 fab 按钮
像这样我需要它:

您可以使用NestedScrollConnection和AnimatedVisibility来更改 的可见性ExtendedFloatingActionButton。
remeberSaveable来存储以下状态ExtendedFloatingActionButton:// Visibility for FAB, could be saved in viewModel
val isVisible = rememberSaveable { mutableStateOf(true) }
Run Code Online (Sandbox Code Playgroud)
NestedScrollConnection,您可以使用您的值来显示/隐藏 FAB:// Nested scroll for control FAB
val nestedScrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
// Hide FAB
if (available.y < -1) {
isVisible.value = false
}
// Show FAB
if (available.y > 1) {
isVisible.value = true
}
return Offset.Zero
}
}
}
Run Code Online (Sandbox Code Playgroud)
ExtendedFloatingActionButtoninside AnimatedVisibility,设置可见值isVisible并设置进入和退出动画,在我的例子中,我用于slideInVertically进入动画和slideOutVertically退出动画:AnimatedVisibility(
visible = isVisible.value,
enter = slideInVertically(initialOffsetY = { it * 2 }),
exit = slideOutVertically(targetOffsetY = { it * 2 }),
) {
ExtendedFloatingActionButton(
onClick = {
// FAB click
}
) {
Text(
text = "Extended FAB"
)
}
}
Run Code Online (Sandbox Code Playgroud)
NestedScrollConnection于可滚动内容,在我的例子中LazyColumn:LazyColumn(
modifier = Modifier
.fillMaxWidth()
.padding(innerPadding)
.nestedScroll(nestedScrollConnection),
) {
items(100) { index ->
Text(
modifier = Modifier.padding(16.dp),
text = "Item: $index"
)
}
}
Run Code Online (Sandbox Code Playgroud)
MainActivity的完整代码:
package com.andreirozov.animatedfab
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Add
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.FabPosition
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.unit.dp
import com.andreirozov.animatedfab.ui.theme.AnimatedFabTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AnimatedFabApp()
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AnimatedFabApp() {
AnimatedFabTheme {
// Visibility for FAB, could be saved in viewModel
val isVisible = rememberSaveable { mutableStateOf(true) }
// Nested scroll for control FAB
val nestedScrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
// Hide FAB
if (available.y < -1) {
isVisible.value = false
}
// Show FAB
if (available.y > 1) {
isVisible.value = true
}
return Offset.Zero
}
}
}
Scaffold(
floatingActionButtonPosition = FabPosition.Center,
floatingActionButton = {
AnimatedVisibility(
visible = isVisible.value,
enter = slideInVertically(initialOffsetY = { it * 2 }),
exit = slideOutVertically(targetOffsetY = { it * 2 }),
) {
ExtendedFloatingActionButton(
onClick = {
// FAB click
}
) {
Text(
text = "Extended FAB"
)
}
}
}
) { innerPadding ->
LazyColumn(
modifier = Modifier
.fillMaxWidth()
.padding(innerPadding)
.nestedScroll(nestedScrollConnection),
) {
items(100) { index ->
Text(
modifier = Modifier.padding(16.dp),
text = "Item: $index"
)
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
您需要监听滚动状态并应用AnimatedVisibiltiy。LazyColumn这是一个使用with的示例LazyListState(您也可以使用Columnwith ScrollState)
@Composable
fun Screen() {
val listState = rememberLazyListState()
val fabVisibility by derivedStateOf {
listState.firstVisibleItemIndex == 0
}
Box(modifier = Modifier.fillMaxSize()) {
LazyColumn(
Modifier.fillMaxSize(),
state = listState,
) {
items(count = 100, key = { it.toString() }) {
Text(modifier = Modifier.fillMaxWidth(),
text = "Hello $it!")
}
}
AddPaymentFab(
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(bottom = 40.dp),
isVisibleBecauseOfScrolling = fabVisibility
)
}
}
@Composable
private fun AddPaymentFab(
modifier: Modifier,
isVisibleBecauseOfScrolling: Boolean,
) {
val density = LocalDensity.current
AnimatedVisibility(
modifier = modifier,
visible = isVisibleBecauseOfScrolling,
enter = slideInVertically {
with(density) { 40.dp.roundToPx() }
} + fadeIn(),
exit = fadeOut(
animationSpec = keyframes {
this.durationMillis = 120
}
)
) {
ExtendedFloatingActionButton(
text = { Text(text = "Add Payment") },
onClick = { },
icon = { Icon(Icons.Filled.Add, "Add Payment") }
)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4024 次 |
| 最近记录: |