import 'package:flutter/material.dart'; /// 可伸缩容器 class ExpandableContainer extends StatefulWidget { final Widget child; final bool expanded; final double collapsedHeight; final double expandedHeight; final double fixedWidth; ExpandableContainer({ required this.child, this.expanded = false, this.collapsedHeight = 40.0, this.expandedHeight = 200.0, this.fixedWidth = 250.0, }); @override _ExpandableContainerState createState() => _ExpandableContainerState(); } class _ExpandableContainerState extends State with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation _heightFactor; @override void initState() { super.initState(); _controller = AnimationController( vsync: this, duration: Duration(milliseconds: 500), ); final double initialHeightFactor = widget.expanded ? 1.0 : 0.0; _heightFactor = _controller .drive( CurveTween(curve: Curves.fastOutSlowIn), ) .drive( Tween(begin: initialHeightFactor, end: 1.0), ); if (widget.expanded) { _controller.value = 1.0; } } @override void didUpdateWidget(ExpandableContainer oldWidget) { super.didUpdateWidget(oldWidget); if (widget.expanded != oldWidget.expanded) { if (widget.expanded) { _controller.forward(); } else { _controller.reverse(); } } } @override void dispose() { _controller.dispose(); super.dispose(); } void _toggleExpanded() { print("toggleExpanded"); if (_controller.isAnimating) { return; } final bool isExpanded = _heightFactor.value == 1.0; _controller.fling( velocity: isExpanded ? -2.0 : 2.0, ); } @override Widget build(BuildContext context) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: _toggleExpanded, child: AnimatedSize( duration: Duration(milliseconds: 500), child: AnimatedBuilder( animation: _heightFactor, builder: (BuildContext context, Widget? child) { return Container( width: widget.fixedWidth, height: widget.collapsedHeight + (_heightFactor.value * (widget.expandedHeight - widget.collapsedHeight)), child: child, ); }, child: widget.child, ), ), ); } }