import 'package:extended_image/extended_image.dart'; import 'package:flutter/material.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart'; import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart'; /// make hero better when slide out class HeroWidget extends StatefulWidget { const HeroWidget( {required this.child, required this.tag, required this.slidePagekey, this.slideType = SlideType.onlyImage, Key? key}) : super(key: key); final Widget child; final SlideType slideType; final Object tag; final GlobalKey slidePagekey; @override _HeroWidgetState createState() => _HeroWidgetState(); } class _HeroWidgetState extends TIMUIKitState { RectTween? _rectTween; @override Widget tuiBuild(BuildContext context, TUIKitBuildValue value) { return Hero( tag: widget.tag, createRectTween: (Rect? begin, Rect? end) { _rectTween = RectTween(begin: begin, end: end); return _rectTween!; }, // make hero better when slide out flightShuttleBuilder: (BuildContext flightContext, Animation animation, HeroFlightDirection flightDirection, BuildContext fromHeroContext, BuildContext toHeroContext) { // make hero more smoothly final Hero hero = (flightDirection == HeroFlightDirection.pop ? fromHeroContext.widget : toHeroContext.widget) as Hero; if (_rectTween == null) { return hero; } if (flightDirection == HeroFlightDirection.pop) { final bool fixTransform = widget.slideType == SlideType.onlyImage && (widget.slidePagekey.currentState!.offset != Offset.zero || widget.slidePagekey.currentState!.scale != 1.0); final Widget toHeroWidget = (toHeroContext.widget as Hero).child; return AnimatedBuilder( animation: animation, builder: (BuildContext buildContext, Widget? child) { Widget animatedBuilderChild = hero.child; // make hero more smoothly animatedBuilderChild = Stack( clipBehavior: Clip.antiAlias, alignment: Alignment.center, children: [ Opacity( opacity: 1 - animation.value, child: UnconstrainedBox( child: SizedBox( width: _rectTween!.begin!.width, height: _rectTween!.begin!.height, child: toHeroWidget, ), ), ), Opacity( opacity: animation.value, child: animatedBuilderChild, ) ], ); // fix transform when slide out if (fixTransform) { final Tween offsetTween = Tween( begin: Offset.zero, end: widget.slidePagekey.currentState!.offset); final Tween scaleTween = Tween( begin: 1.0, end: widget.slidePagekey.currentState!.scale); animatedBuilderChild = Transform.translate( offset: offsetTween.evaluate(animation), child: Transform.scale( scale: scaleTween.evaluate(animation), child: animatedBuilderChild, ), ); } return animatedBuilderChild; }, ); } return hero.child; }, child: widget.child, ); } }