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

Flutter:如何在更高高度的容器后方渲染容器(动态高度场景)

在Flutter中实现动态高度容器后方渲染的解决方案

要实现将一个容器渲染在另一个动态高度容器的后方,可以通过Stack布局结合动态尺寸获取来解决,核心思路是先获取上层容器的实际渲染高度,再给后方容器设置更大的高度并定位对齐,具体实现如下:

步骤1:使用Stack叠加容器

Stack的子组件遵循“越靠后层级越高”的规则,因此需要将后方容器放在Stack子列表的前面,上层容器(你的QuotifyrBottomSheet)放在后面,确保上层容器覆盖在后方容器之上。

步骤2:获取上层容器的动态高度

由于上层容器高度是运行时计算的,我们可以通过GlobalKey在UI渲染完成后获取其实际尺寸,再用ResizeObserver监听尺寸变化,适配动态高度更新。

完整代码示例

import 'package:flutter/material.dart';
import 'package:quotifyr/configs/theme/theme.dart';

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

  @override
  State<DemoPage> createState() => _DemoPageState();
}

class _DemoPageState extends State<DemoPage> {
  final GlobalKey _bottomSheetKey = GlobalKey();
  double _bottomSheetHeight = 0;
  ResizeObserver? _resizeObserver;

  @override
  void initState() {
    super.initState();
    // 等待UI首次渲染完成后获取初始高度
    WidgetsBinding.instance.addPostFrameCallback((_) {
      final renderBox = _bottomSheetKey.currentContext?.findRenderObject() as RenderBox?;
      if (renderBox != null) {
        setState(() {
          _bottomSheetHeight = renderBox.size.height;
        });
        // 监听容器尺寸变化,适配动态高度更新
        _resizeObserver = ResizeObserver(
          onResize: (size) {
            setState(() {
              _bottomSheetHeight = size.height;
            });
          },
        );
        _resizeObserver?.observe(renderBox);
      }
    });
  }

  @override
  void dispose() {
    _resizeObserver?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey[200],
      body: Stack(
        alignment: Alignment.bottomCenter,
        children: [
          // 后方容器:高度比上层容器高,底部对齐
          if (_bottomSheetHeight > 0)
            Positioned(
              bottom: 0,
              left: 0,
              right: 0,
              child: Container(
                // 自定义高度,比如比上层高80px
                height: _bottomSheetHeight + 80,
                decoration: const BoxDecoration(
                  color: Color(0xFF4A90E2),
                  borderRadius: BorderRadius.only(
                    topLeft: Radius.circular(15),
                    topRight: Radius.circular(15),
                  ),
                ),
              ),
            ),
          // 上层动态高度容器
          QuotifyrBottomSheet(
            key: _bottomSheetKey,
            child: SizedBox(
              // 示例动态高度:屏幕高度的40%
              height: MediaQuery.of(context).size.height * 0.4,
              child: const Padding(
                padding: EdgeInsets.all(20),
                child: Text("上层动态高度容器内容"),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

// 你的QuotifyrBottomSheet原代码保持不变
class QuotifyrBottomSheet extends StatelessWidget {
  const QuotifyrBottomSheet({
    super.key,
    this.child,
    this.height,
    this.width,
  });

  final Widget? child;
  final double? height;
  final double? width;

  @override
  Widget build(BuildContext context) {
    final QuotifyrColors colors =
        Theme.of(context).extension<QuotifyrColors>()!;
    return Container(
      height: height,
      width: width,
      decoration: BoxDecoration(
        color: colors.surface,
        borderRadius: const BorderRadius.only(
          topLeft: Radius.circular(15.0),
          topRight: Radius.circular(15.0),
        ),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.2),
            offset: const Offset(0, -4),
            blurRadius: 16,
          ),
        ],
      ),
      child: child,
    );
  }
}

关键细节说明

  1. 尺寸监听:使用ResizeObserver(Flutter 3.10+支持)可以实时监听上层容器的尺寸变化,确保后方容器高度能动态适配。
  2. 定位对齐:通过Positioned将后方容器与上层容器底部对齐,保证视觉上的连贯性。
  3. 层级控制:Stack子组件的顺序决定了渲染层级,后方容器必须放在上层容器之前。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 00:07:04