| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 | import 'package:flutter/material.dart';class AnimatedPanel extends StatefulWidget {  final bool isClosed;  final double closedX;  final double closedY;  final double duration;  final Curve? curve;  final Widget? child;  const AnimatedPanel(      {Key? key,      this.isClosed = false,      this.closedX = 0.0,      this.closedY = 0.0,      this.duration = 0.0,      this.curve,      this.child})      : super(key: key);  @override  _AnimatedPanelState createState() => _AnimatedPanelState();}class _AnimatedPanelState extends State<AnimatedPanel> {  bool _isHidden = true;  @override  Widget build(BuildContext context) {    Offset closePos = Offset(widget.closedX, widget.closedY);    double duration = _isHidden && widget.isClosed ? 0 : widget.duration;    return TweenAnimationBuilder(      curve: widget.curve ?? Curves.easeOut,      tween: Tween<Offset>(        begin: !widget.isClosed ? Offset.zero : closePos,        end: !widget.isClosed ? Offset.zero : closePos,      ),      duration: Duration(milliseconds: (duration * 1000).round()),      builder: (_, Offset value, Widget? c) {        _isHidden =            widget.isClosed && value == Offset(widget.closedX, widget.closedY);        return _isHidden            ? Container()            : Transform.translate(offset: value, child: c);      },      child: widget.child,    );  }}extension AnimatedPanelExtensions on Widget {  Widget animatedPanelX(          {double closeX = 0.0,          bool? isClosed,          double? duration,          Curve? curve}) =>      animatedPanel(          closePos: Offset(closeX, 0),          isClosed: isClosed,          curve: curve,          duration: duration);  Widget animatedPanelY(          {double closeY = 0.0,          bool? isClosed,          double? duration,          Curve? curve}) =>      animatedPanel(          closePos: Offset(0, closeY),          isClosed: isClosed,          curve: curve,          duration: duration);  Widget animatedPanel(      {required Offset closePos,      bool? isClosed,      double? duration,      Curve? curve}) {    return AnimatedPanel(        closedX: closePos.dx,        closedY: closePos.dy,        child: this,        isClosed: isClosed ?? false,        duration: duration ?? .35,        curve: curve);  }}
 |