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

Flutter如何实现类似Google Assistant的半屏界面效果

类Google Assistant半屏效果参考

Flutter实现类Google Assistant半屏界面方案

核心实现思路

  • 这类半屏界面本质是支持多状态锚点、可手势拖拽的底部悬浮面板,和普通底部弹窗的核心差异是:支持半开、全展开、关闭多档位停留,可通过上下拖拽调整高度,面板展示时下层主界面不会被强制遮罩拦截,仍可正常交互,完全匹配Google Assistant的交互逻辑。
  • 无需从零开发手势监听、动画联动逻辑,优先使用Flutter官方内置组件实现,复杂场景可搭配成熟社区封装,稳定性和交互手感都有保障。

具体实现方式

方案1:官方内置组件实现(无第三方依赖,优先推荐)

使用Flutter SDK自带的DraggableScrollableSheet组件即可快速实现基础效果,步骤如下:

  1. 将主界面、半屏面板统一放在Stack堆叠布局中,主界面置于下层,半屏面板置于上层,保证下层内容可正常响应交互。
  2. 配置面板核心参数匹配半屏效果:
    • initialChildSize:初始展示高度占屏幕的比例,设置为0.5即为默认半屏状态,和Google Assistant弹出高度一致
    • minChildSize:下拉到最低位置的高度比例,设置为0即下拉到最底部完全关闭面板
    • maxChildSize:上拉到最高位置的高度比例,一般设置为0.9~1.0,对应接近全屏的展开状态
    • snap:开启档位吸附,拖拽停止时自动吸附到最近的高度档位,交互手感更贴近原生系统

最简实现代码示例:

import 'package:flutter/material.dart';

class HalfScreenDemo extends StatelessWidget {
  const HalfScreenDemo({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          // 下层主界面内容
          const Center(
            child: Text("主界面区域,半屏弹出时仍可正常点击交互"),
          ),
          // 上层可拖拽半屏面板
          DraggableScrollableSheet(
            initialChildSize: 0.5,
            minChildSize: 0,
            maxChildSize: 0.95,
            snap: true,
            builder: (context, scrollController) {
              return Container(
                decoration: const BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
                  boxShadow: [BoxShadow(blurRadius: 12, color: Colors.black12)]
                ),
                child: Column(
                  children: [
                    // 顶部拖拽指示条
                    Container(
                      margin: const EdgeInsets.symmetric(vertical: 8),
                      width: 40,
                      height: 4,
                      decoration: BoxDecoration(
                        color: Colors.grey[300],
                        borderRadius: BorderRadius.circular(2)
                      ),
                    ),
                    // 面板内可滚动内容,必须绑定组件传入的scrollController
                    Expanded(
                      child: ListView.builder(
                        controller: scrollController,
                        itemCount: 30,
                        itemBuilder: (context, index) => ListTile(
                          title: Text("面板内容项 $index"),
                        ),
                      ),
                    )
                  ],
                ),
              );
            },
          )
        ],
      ),
    );
  }
}

如果需要控制面板的显示/隐藏,直接用状态变量搭配Offstage或Visibility组件包裹面板即可。

方案2:社区封装组件(适配复杂交互场景)

如果需要更贴近Google Assistant的精细交互,比如手势冲突自动处理、面板状态实时监听、多锚点自定义配置、动态背景效果,可以引入pub上的sliding_sheet组件:

  • 支持配置任意多个高度吸附锚点,可精准设置关闭、半屏、大半屏、全屏等多档位
  • 自动处理面板和内部滚动组件(ListView、GridView等)的手势冲突,不会出现拖拽卡顿
  • 提供面板展开进度回调,可根据进度动态调整背景模糊度、面板圆角等视觉效果
    使用时直接替换DraggableScrollableSheet,通过snapSpec参数配置锚点即可,例如snapSpec: const SnapSpec(snaps: [0, 0.5, 0.95])就可以实现关闭、半屏、全屏三个档位的吸附效果。

体验优化细节

  • 面板顶部增加短横条样式的拖拽指示器,给用户明确的可拖拽交互提示
  • 面板初始状态只保留顶部圆角,当面板上拉到接近全屏时,动态将顶部圆角调整为0,过渡更自然
  • 不要使用不透明的遮罩层挡住下层内容,如果需要突出面板,可以根据面板展开高度动态添加高斯模糊效果,不影响下层交互
  • 适配返回键逻辑:面板处于打开状态时,点击返回键优先关闭面板,而非直接退出当前页面

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 21:45:39