You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jetpack Compose中带过渡效果实现滚动隐藏FAB按钮

实现效果

滚动时FAB隐藏/显示过渡效果

实现思路
  • 首先通过滚动状态对象监听页面滚动方向与偏移量
  • 使用derivedStateOf封装滚动判断逻辑,减少不必要的重组触发
  • 搭配Compose自带的动画API实现FAB的平滑过渡效果
代码实现

以下为LazyColumn场景下的完整示例:

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
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.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

@Composable
fun ScrollHideFabDemo() {
    val listState = rememberLazyListState()
    // 示例逻辑:页面回到顶部时显示FAB,滚动时隐藏
    val showFab by remember {
        derivedStateOf {
            listState.firstVisibleItemIndex == 0 && listState.firstVisibleItemScrollOffset == 0
        }
    }

    Scaffold(
        floatingActionButton = {
            AnimatedVisibility(
                visible = showFab,
                // 自定义进入动画:从底部滑入+淡入
                enter = slideInVertically(initialOffsetY = { it * 2 }) + fadeIn(),
                // 自定义退出动画:向下滑出+淡出
                exit = slideOutVertically(targetOffsetY = { it * 2 }) + fadeOut()
            ) {
                FloatingActionButton(
                    onClick = { /* 补充FAB点击逻辑 */ }
                ) {
                    Icon(Icons.Default.Add, contentDescription = "新增")
                }
            }
        }
    ) { innerPadding ->
        LazyColumn(
            state = listState,
            modifier = Modifier.padding(innerPadding)
        ) {
            items(50) { index ->
                Text(
                    text = "列表项 $index",
                    modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp)
                )
            }
        }
    }
}
适配说明
  • 若使用普通可滚动Column,将rememberLazyListState替换为rememberScrollState(),判断逻辑改为scrollState.value == 0即可
  • 可调整动画的animationSpec参数自定义动画时长、插值器,匹配项目设计规范
  • 如果需要实现"只要向下滚动就隐藏、向上滚动就显示"的逻辑,而非仅在顶部显示,可修改derivedStateOf中的判断逻辑,对比前后滚动偏移的差值即可

内容的提问来源于stack exchange,提问作者GvHarish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 12:09:02