Skip to content

Instantly share code, notes, and snippets.

@take4blue
Created April 26, 2023 05:33
Show Gist options
  • Save take4blue/5e8a3a00a344b0ff94245d196763d836 to your computer and use it in GitHub Desktop.
Save take4blue/5e8a3a00a344b0ff94245d196763d836 to your computer and use it in GitHub Desktop.
位置指定と配置したダイアログ基準としたTransitionアニメーションのサンプル
import 'package:aligned_dialog/aligned_dialog.dart';
import 'package:flutter/material.dart';
void main() => runApp(const GeneralDialogApp());
class GeneralDialogApp extends StatelessWidget {
const GeneralDialogApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
restorationScopeId: 'app',
home: GeneralDialogExample(),
);
}
}
class GeneralDialogExample extends StatelessWidget {
const GeneralDialogExample({super.key});
@override
Widget build(BuildContext context) {
final key = GlobalKey<_MyDialogState>();
return Scaffold(
body: Center(
child: Builder(builder: (context) {
return OutlinedButton(
onPressed: () {
// これで位置指定でウィジェットを表示する。
// GlobalKey経由でtransitionsBuilder内でanimationをState側に
// 渡してアニメーション動作を実施する
showAlignedDialog(
context: context,
builder: (context) => MyDialog(
key: key,
child: const SizedBox(
width: 100,
height: 100,
child: Center(child: Text('Alert!'))),
),
transitionsBuilder:
(context, animation, secondaryAnimation, child) {
key.currentState?.animation = animation;
return child;
},
followerAnchor: Alignment.topCenter,
targetAnchor: Alignment.bottomCenter,
);
},
child: const Text('Open Dialog'),
);
}),
),
);
}
}
/// [ProxyAnimation]に[Animation]を渡せるように[StatefulWidget]にして
/// [child]をダイアログ化するウィジェット
class MyDialog extends StatefulWidget {
const MyDialog({required this.child, super.key});
final Widget child;
@override
State<MyDialog> createState() => _MyDialogState();
}
class _MyDialogState extends State<MyDialog> {
final ProxyAnimation _animation = ProxyAnimation();
set animation(Animation<double> value) => _animation.parent = value;
@override
Widget build(BuildContext context) {
return FadeTransition(
opacity: _animation,
child: ScaleTransition(
scale: _animation,
alignment: Alignment.topLeft,
child: RotationTransition(
turns: _animation,
child: Material(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4.0))),
child: widget.child),
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment