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

含Row子组件的AnimatedContainer无法动画问题求助

解决AnimatedSize中Row组件不动画的问题

你的问题核心是Row组件缺少明确的宽度约束,导致AnimatedSize无法正确计算其尺寸变化,从而中断动画。当使用Text作为header时,Text会自动填充父级宽度,但Row默认会根据子组件尺寸自适应,在高度收缩到0的过程中,Row的宽度约束丢失,动画无法正常执行。

解决方案:给Row包裹一个充满父级宽度的容器

只需要将Row放在一个设置了width: double.infinity的Container中,让Row明确继承父级的宽度约束,这样AnimatedSize就能正确追踪尺寸变化,恢复动画效果。

修改后的AnimatedCardList中对应代码片段:

BasicCard(
  isCardView: isCardView,
  header: Container(
    width: double.infinity, // 关键:让Row充满父级宽度
    child: Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: const [
        Text("Card View With Row Now Animating"),
        Text("Edit >"),
      ],
    ),
  ),
),

完整修改后的代码

import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool cardView = true;
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: AnimatedCardList(
          isCardView: cardView,
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            setState(() {
              cardView = !cardView;
            });
          },
          backgroundColor: Colors.black,
          child: Icon(
            cardView ? Icons.check_rounded : Icons.edit,
            size: 40,
            color: Colors.white,
          ),
        ),
      ),
    );
  }
}

class AnimatedCardList extends StatelessWidget {
  final bool isCardView;
  const AnimatedCardList({
    super.key,
    required this.isCardView,
  });
  @override
  Widget build(BuildContext context) {
    return AnimatedContainer(
      duration: const Duration(seconds: 2),
      padding: isCardView ? EdgeInsets.zero : const EdgeInsets.all(10),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          BasicCard(
            isCardView: isCardView,
            header: Container(
              width: double.infinity,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: const [
                  Text("Card View With Row Now Animating"),
                  Text("Edit >"),
                ],
              ),
            ),
          ),
          const SizedBox(height: 50),
          BasicCard(
            isCardView: isCardView,
            header: const Text("Card View No Row IS Animating"),
          ),
        ],
      ),
    );
  }
}

class BasicCard extends StatelessWidget {
  final Widget header;
  const BasicCard({
    Key? key,
    required this.isCardView,
    required this.header,
  }) : super(key: key);

  final bool isCardView;

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      child: Column(
        children: [
          AnimatedSize(
            duration: const Duration(seconds: 2),
            child: Container(
              color: Colors.blue,
              constraints: !isCardView
                  ? const BoxConstraints(
                      maxHeight: double.infinity,
                    )
                  : const BoxConstraints(
                      maxHeight: 0.0,
                    ),
              child: header,
            ),
          ),
          const Text("Card Content")
        ],
      ),
    );
  }
}

为什么这样能解决问题?

  • 当Row被包裹在宽度充满父级的Container中时,Row会获得明确的宽度约束,不会在动画过程中因为尺寸不确定导致布局异常。
  • AnimatedSize依赖子组件的尺寸变化来驱动动画,明确的约束让它能正确计算从初始高度到0的过渡过程,保证动画流畅执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 08:05:22