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

Flutter中打开Bottom Sheet时如何移动页面容器?

实现Bottom Sheet弹出时自动移动Container的方案

要实现Bottom Sheet打开时首页的Container自动移动,核心是通过状态管理控制Container的位置,结合Flutter的动画组件让移动效果更流畅。以下是具体实现步骤和修改后的代码:

核心思路

  1. 用AnimatedPositioned替代原代码中的Positioned,实现位置变化的平滑过渡动画
  2. 在弹出Bottom Sheet前,更新Container的目标位置;关闭Bottom Sheet时,恢复其原有位置(可选,根据需求调整)
  3. 通过setState触发UI更新,结合showModalBottomSheet的whenComplete回调处理关闭后的逻辑

修改后的完整代码

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  bool _bottomSheetVisible = false;
  double _containerPositionX = 0.0;
  double _containerPositionY = 0.0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Moveable Container'),
      ),
      body: Stack(
        children: [
          // 替换为AnimatedPositioned实现平滑动画
          AnimatedPositioned(
            left: _containerPositionX,
            top: _containerPositionY,
            duration: const Duration(milliseconds: 300), // 动画时长
            child: GestureDetector(
              onPanUpdate: (details) {
                setState(() {
                  _containerPositionX += details.delta.dx;
                  _containerPositionY += details.delta.dy;
                });
              },
              child: Container(
                width: 100,
                height: 100,
                color: Colors.blue,
                child: const Center(
                  child: Text(
                    'Move Me',
                    style: TextStyle(color: Colors.white),
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 保存当前位置,用于关闭Bottom Sheet后恢复
          final double oldPosX = _containerPositionX;
          final double oldPosY = _containerPositionY;

          setState(() {
            _bottomSheetVisible = true;
            // 设置Bottom Sheet打开时Container的目标位置
            _containerPositionX = MediaQuery.of(context).size.width - 120; // 靠右(减去容器宽度+边距)
            _containerPositionY = 200; // 向下移动到指定位置
          });

          showModalBottomSheet(
            context: context,
            builder: (BuildContext context) {
              return Container(
                height: 200,
                color: Colors.white,
                child: const Center(
                  child: Text('Bottom Sheet Content'),
                ),
              );
            },
          ).whenComplete(() {
            setState(() {
              _bottomSheetVisible = false;
              // 恢复Container原来的位置
              _containerPositionX = oldPosX;
              _containerPositionY = oldPosY;
            });
          });
        },
        child: const Icon(Icons.add),
      ),
    );
  }
}

关键代码说明

  • AnimatedPositioned:替代普通Positioned,仅需设置duration就能自动实现位置变化的过渡动画,无需手动管理AnimationController,简化代码
  • 位置保存与恢复:在弹出Bottom Sheet前记录当前位置,关闭时通过whenComplete回调恢复,保证交互的连贯性
  • 动态位置计算:使用MediaQuery.of(context).size.width获取屏幕宽度,让Container的目标位置适配不同屏幕尺寸

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 18:57:46