opt: close popup dialog with anim

This commit is contained in:
bggRGjQaUbCoE
2024-09-01 12:46:07 +08:00
parent 2cc537b715
commit b87a432711
8 changed files with 78 additions and 49 deletions

View File

@@ -1,11 +1,16 @@
import 'package:PiliPalaX/common/widgets/no_splash_factory.dart';
import 'package:PiliPalaX/common/widgets/overlay_pop.dart';
import 'package:flutter/material.dart';
class AnimatedDialog extends StatefulWidget {
const AnimatedDialog({Key? key, required this.child, this.closeFn})
: super(key: key);
const AnimatedDialog({
Key? key,
required this.videoItem,
required this.closeFn,
}) : super(key: key);
final Widget child;
final Function? closeFn;
final dynamic videoItem;
final Function closeFn;
@override
State<StatefulWidget> createState() => AnimatedDialogState();
@@ -13,44 +18,53 @@ class AnimatedDialog extends StatefulWidget {
class AnimatedDialogState extends State<AnimatedDialog>
with SingleTickerProviderStateMixin {
late AnimationController? controller;
late Animation<double>? opacityAnimation;
late Animation<double>? scaleAnimation;
late AnimationController controller;
late Animation<double> opacityAnimation;
late Animation<double> scaleAnimation;
@override
void initState() {
super.initState();
controller = AnimationController(
vsync: this, duration: const Duration(milliseconds: 800));
opacityAnimation = Tween<double>(begin: 0.0, end: 0.6).animate(
CurvedAnimation(parent: controller!, curve: Curves.easeOutExpo));
scaleAnimation =
CurvedAnimation(parent: controller!, curve: Curves.easeOutExpo);
controller!.addListener(() => setState(() {}));
controller!.forward();
vsync: this, duration: const Duration(milliseconds: 255));
opacityAnimation = Tween<double>(begin: 0.0, end: 0.6)
.animate(CurvedAnimation(parent: controller, curve: Curves.linear));
scaleAnimation = CurvedAnimation(parent: controller, curve: Curves.linear);
controller.addListener(() => setState(() {}));
controller.forward();
}
@override
void dispose() {
controller!.removeListener(() {});
controller!.dispose();
controller.removeListener(() {});
controller.dispose();
super.dispose();
}
void closeFn() async {
await controller.reverse();
widget.closeFn();
}
@override
Widget build(BuildContext context) {
return Material(
color: Colors.black.withOpacity(opacityAnimation!.value),
color: Colors.black.withOpacity(opacityAnimation.value),
child: InkWell(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
onTap: () => widget.closeFn!(),
splashFactory: NoSplashFactory(),
onTap: closeFn,
child: Center(
child: FadeTransition(
opacity: scaleAnimation!,
opacity: scaleAnimation,
child: ScaleTransition(
scale: scaleAnimation!,
child: widget.child,
scale: scaleAnimation,
child: OverlayPop(
videoItem: widget.videoItem,
closeFn: closeFn,
),
),
),
),

View File

@@ -0,0 +1,34 @@
import 'package:flutter/material.dart';
class NoSplashFactory extends InteractiveInkFeatureFactory {
@override
InteractiveInkFeature create(
{required MaterialInkController controller,
required RenderBox referenceBox,
required Offset position,
required Color color,
required TextDirection textDirection,
bool containedInkWell = false,
RectCallback? rectCallback,
BorderRadius? borderRadius,
ShapeBorder? customBorder,
double? radius,
VoidCallback? onRemoved}) {
return _NoInteractiveInkFeature(
controller: controller,
referenceBox: referenceBox,
color: color,
onRemoved: onRemoved);
}
}
class _NoInteractiveInkFeature extends InteractiveInkFeature {
@override
void paintFeature(Canvas canvas, Matrix4 transform) {}
_NoInteractiveInkFeature({
required super.controller,
required super.referenceBox,
required super.color,
super.onRemoved,
});
}

View File

@@ -14,12 +14,12 @@ class OverlayPop extends StatelessWidget {
@override
Widget build(BuildContext context) {
final double imgWidth = min(Get.height,Get.width) - 8 * 2;
final double imgWidth = min(Get.height, Get.width) - 8 * 2;
return Container(
margin: const EdgeInsets.symmetric(horizontal: 8),
width: imgWidth,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.background,
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(10.0),
),
child: Column(
@@ -47,7 +47,7 @@ class OverlayPop extends StatelessWidget {
child: IconButton(
tooltip: '关闭',
style: ButtonStyle(
padding: MaterialStateProperty.all(EdgeInsets.zero),
padding: WidgetStateProperty.all(EdgeInsets.zero),
),
onPressed: () => closeFn!(),
icon: const Icon(
@@ -79,7 +79,7 @@ class OverlayPop extends StatelessWidget {
? videoItem.pic as String
: videoItem.cover as String,
);
// closeFn!();
closeFn!();
},
icon: const Icon(Icons.download, size: 20),
)