mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-05-30 23:58:13 +08:00
opt: close popup dialog with anim
This commit is contained in:
@@ -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';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class AnimatedDialog extends StatefulWidget {
|
class AnimatedDialog extends StatefulWidget {
|
||||||
const AnimatedDialog({Key? key, required this.child, this.closeFn})
|
const AnimatedDialog({
|
||||||
: super(key: key);
|
Key? key,
|
||||||
|
required this.videoItem,
|
||||||
|
required this.closeFn,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
final Widget child;
|
final dynamic videoItem;
|
||||||
final Function? closeFn;
|
final Function closeFn;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => AnimatedDialogState();
|
State<StatefulWidget> createState() => AnimatedDialogState();
|
||||||
@@ -13,44 +18,53 @@ class AnimatedDialog extends StatefulWidget {
|
|||||||
|
|
||||||
class AnimatedDialogState extends State<AnimatedDialog>
|
class AnimatedDialogState extends State<AnimatedDialog>
|
||||||
with SingleTickerProviderStateMixin {
|
with SingleTickerProviderStateMixin {
|
||||||
late AnimationController? controller;
|
late AnimationController controller;
|
||||||
late Animation<double>? opacityAnimation;
|
late Animation<double> opacityAnimation;
|
||||||
late Animation<double>? scaleAnimation;
|
late Animation<double> scaleAnimation;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
controller = AnimationController(
|
controller = AnimationController(
|
||||||
vsync: this, duration: const Duration(milliseconds: 800));
|
vsync: this, duration: const Duration(milliseconds: 255));
|
||||||
opacityAnimation = Tween<double>(begin: 0.0, end: 0.6).animate(
|
opacityAnimation = Tween<double>(begin: 0.0, end: 0.6)
|
||||||
CurvedAnimation(parent: controller!, curve: Curves.easeOutExpo));
|
.animate(CurvedAnimation(parent: controller, curve: Curves.linear));
|
||||||
scaleAnimation =
|
scaleAnimation = CurvedAnimation(parent: controller, curve: Curves.linear);
|
||||||
CurvedAnimation(parent: controller!, curve: Curves.easeOutExpo);
|
controller.addListener(() => setState(() {}));
|
||||||
controller!.addListener(() => setState(() {}));
|
controller.forward();
|
||||||
controller!.forward();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
controller!.removeListener(() {});
|
controller.removeListener(() {});
|
||||||
controller!.dispose();
|
controller.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void closeFn() async {
|
||||||
|
await controller.reverse();
|
||||||
|
widget.closeFn();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Material(
|
return Material(
|
||||||
color: Colors.black.withOpacity(opacityAnimation!.value),
|
color: Colors.black.withOpacity(opacityAnimation.value),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
|
highlightColor: Colors.transparent,
|
||||||
splashColor: Colors.transparent,
|
splashColor: Colors.transparent,
|
||||||
onTap: () => widget.closeFn!(),
|
splashFactory: NoSplashFactory(),
|
||||||
|
onTap: closeFn,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: FadeTransition(
|
child: FadeTransition(
|
||||||
opacity: scaleAnimation!,
|
opacity: scaleAnimation,
|
||||||
child: ScaleTransition(
|
child: ScaleTransition(
|
||||||
scale: scaleAnimation!,
|
scale: scaleAnimation,
|
||||||
child: widget.child,
|
child: OverlayPop(
|
||||||
|
videoItem: widget.videoItem,
|
||||||
|
closeFn: closeFn,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
34
lib/common/widgets/no_splash_factory.dart
Normal file
34
lib/common/widgets/no_splash_factory.dart
Normal 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,
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -14,12 +14,12 @@ class OverlayPop extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
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(
|
return Container(
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 8),
|
margin: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
width: imgWidth,
|
width: imgWidth,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).colorScheme.background,
|
color: Theme.of(context).colorScheme.surface,
|
||||||
borderRadius: BorderRadius.circular(10.0),
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
@@ -47,7 +47,7 @@ class OverlayPop extends StatelessWidget {
|
|||||||
child: IconButton(
|
child: IconButton(
|
||||||
tooltip: '关闭',
|
tooltip: '关闭',
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
padding: MaterialStateProperty.all(EdgeInsets.zero),
|
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||||
),
|
),
|
||||||
onPressed: () => closeFn!(),
|
onPressed: () => closeFn!(),
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
@@ -79,7 +79,7 @@ class OverlayPop extends StatelessWidget {
|
|||||||
? videoItem.pic as String
|
? videoItem.pic as String
|
||||||
: videoItem.cover as String,
|
: videoItem.cover as String,
|
||||||
);
|
);
|
||||||
// closeFn!();
|
closeFn!();
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.download, size: 20),
|
icon: const Icon(Icons.download, size: 20),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import 'package:flutter/rendering.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:PiliPalaX/common/constants.dart';
|
import 'package:PiliPalaX/common/constants.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/animated_dialog.dart';
|
import 'package:PiliPalaX/common/widgets/animated_dialog.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/overlay_pop.dart';
|
|
||||||
import 'package:PiliPalaX/common/skeleton/video_card_h.dart';
|
import 'package:PiliPalaX/common/skeleton/video_card_h.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/video_card_h.dart';
|
import 'package:PiliPalaX/common/widgets/video_card_h.dart';
|
||||||
@@ -158,10 +157,7 @@ class _HotPageState extends State<HotPage> with AutomaticKeepAliveClientMixin {
|
|||||||
return OverlayEntry(
|
return OverlayEntry(
|
||||||
builder: (context) => AnimatedDialog(
|
builder: (context) => AnimatedDialog(
|
||||||
closeFn: _removePopupDialog,
|
closeFn: _removePopupDialog,
|
||||||
child: OverlayPop(
|
videoItem: videoItem,
|
||||||
videoItem: videoItem,
|
|
||||||
closeFn: _removePopupDialog,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import 'package:PiliPalaX/common/constants.dart';
|
|||||||
import 'package:PiliPalaX/common/skeleton/video_card_v.dart';
|
import 'package:PiliPalaX/common/skeleton/video_card_v.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/animated_dialog.dart';
|
import 'package:PiliPalaX/common/widgets/animated_dialog.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/overlay_pop.dart';
|
|
||||||
import 'package:PiliPalaX/pages/home/index.dart';
|
import 'package:PiliPalaX/pages/home/index.dart';
|
||||||
import 'package:PiliPalaX/pages/main/index.dart';
|
import 'package:PiliPalaX/pages/main/index.dart';
|
||||||
|
|
||||||
@@ -137,10 +136,7 @@ class _LivePageState extends State<LivePage>
|
|||||||
return OverlayEntry(
|
return OverlayEntry(
|
||||||
builder: (context) => AnimatedDialog(
|
builder: (context) => AnimatedDialog(
|
||||||
closeFn: _removePopupDialog,
|
closeFn: _removePopupDialog,
|
||||||
child: OverlayPop(
|
videoItem: liveItem,
|
||||||
videoItem: liveItem,
|
|
||||||
closeFn: _removePopupDialog,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import 'package:flutter/rendering.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:PiliPalaX/common/constants.dart';
|
import 'package:PiliPalaX/common/constants.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/animated_dialog.dart';
|
import 'package:PiliPalaX/common/widgets/animated_dialog.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/overlay_pop.dart';
|
|
||||||
import 'package:PiliPalaX/common/skeleton/video_card_h.dart';
|
import 'package:PiliPalaX/common/skeleton/video_card_h.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/video_card_h.dart';
|
import 'package:PiliPalaX/common/widgets/video_card_h.dart';
|
||||||
@@ -162,10 +161,7 @@ class _ZonePageState extends State<ZonePage>
|
|||||||
return OverlayEntry(
|
return OverlayEntry(
|
||||||
builder: (context) => AnimatedDialog(
|
builder: (context) => AnimatedDialog(
|
||||||
closeFn: _removePopupDialog,
|
closeFn: _removePopupDialog,
|
||||||
child: OverlayPop(
|
videoItem: videoItem,
|
||||||
videoItem: videoItem,
|
|
||||||
closeFn: _removePopupDialog,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,10 +137,7 @@ class _RcmdPageState extends State<RcmdPage>
|
|||||||
return OverlayEntry(
|
return OverlayEntry(
|
||||||
builder: (context) => AnimatedDialog(
|
builder: (context) => AnimatedDialog(
|
||||||
closeFn: _removePopupDialog,
|
closeFn: _removePopupDialog,
|
||||||
child: OverlayPop(
|
videoItem: videoItem,
|
||||||
videoItem: videoItem,
|
|
||||||
closeFn: _removePopupDialog,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import 'package:get/get.dart';
|
|||||||
import 'package:PiliPalaX/common/skeleton/video_card_h.dart';
|
import 'package:PiliPalaX/common/skeleton/video_card_h.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/animated_dialog.dart';
|
import 'package:PiliPalaX/common/widgets/animated_dialog.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/overlay_pop.dart';
|
|
||||||
import 'package:PiliPalaX/common/widgets/video_card_h.dart';
|
import 'package:PiliPalaX/common/widgets/video_card_h.dart';
|
||||||
import '../../../../common/constants.dart';
|
import '../../../../common/constants.dart';
|
||||||
import '../../../../utils/grid.dart';
|
import '../../../../utils/grid.dart';
|
||||||
@@ -117,10 +116,7 @@ class _RelatedVideoPanelState extends State<RelatedVideoPanel>
|
|||||||
return OverlayEntry(
|
return OverlayEntry(
|
||||||
builder: (BuildContext context) => AnimatedDialog(
|
builder: (BuildContext context) => AnimatedDialog(
|
||||||
closeFn: _removePopupDialog,
|
closeFn: _removePopupDialog,
|
||||||
child: OverlayPop(
|
videoItem: videoItem,
|
||||||
videoItem: videoItem,
|
|
||||||
closeFn: _removePopupDialog,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user