Flutter实战技巧之-自定义Dialog动画

先来看看效果图:


GIF Dialog Show.gif

直接上代码吧

import 'package:flutter/material.dart';
import 'package:flutter_demo/common/custom_dialog.dart';

class DialogAnimationPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return DialogAnimationState();
  }
}

class DialogAnimationState extends State<DialogAnimationPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Dialog动画'),
      ),
      body: Column(
        children: <Widget>[
          RaisedButton(
            onPressed: () {
              _showDialog(TransitionType.inFromLeft);
            },
            child: Text('show dialog inFromLeft'),
          ),
          RaisedButton(
            onPressed: () {
              _showDialog(TransitionType.inFromRight);
            },
            child: Text('show dialog inFromRight'),
          ),
          RaisedButton(
            onPressed: () {
              _showDialog(TransitionType.inFromTop);
            },
            child: Text('show dialog inFromTop'),
          ),
          RaisedButton(
            onPressed: () {
              _showDialog(TransitionType.inFromBottom);
            },
            child: Text('show dialog inFromBottom'),
          ),
          RaisedButton(
            onPressed: () {
              _showDialog(TransitionType.scale);
            },
            child: Text('show dialog scale'),
          ),
          RaisedButton(
            onPressed: () {
              _showDialog(TransitionType.rotation);
            },
            child: Text('show dialog rotation'),
          ),
        ],
      ),
    );
  }

  void _showDialog(TransitionType type) {
    showAnimationDialog(
        context: context,
        transitionType: type,
        builder: (context) {
          return AlertDialog(
            title: Text('Dialog Show'),
            content: Text('this is a dialog'),
            actions: <Widget>[
              InkWell(
                child: Text('confirm'),
                onTap: () {
                  Navigator.pop(context);
                },
              ),
              InkWell(
                child: Text('cancel'),
                onTap: () {
                  Navigator.pop(context);
                },
              ),
            ],
          );
        });
  }
}
import 'package:flutter/material.dart';

enum TransitionType {
  inFromLeft,
  inFromRight,
  inFromTop,
  inFromBottom,
  scale,
  fade,
  rotation,
  size,
}

Future<T> showAnimationDialog<T>({
  @required BuildContext context,
  bool barrierDismissible = true,
  @Deprecated('') Widget child,
  WidgetBuilder builder,
  bool useRootNavigator = true,
  RouteSettings routeSettings,
  TransitionType transitionType,
}) {
  assert(child == null || builder == null);
  assert(useRootNavigator != null);
  assert(debugCheckHasMaterialLocalizations(context));

  final ThemeData theme = Theme.of(context, shadowThemeOnly: true);
  return showGeneralDialog(
    context: context,
    pageBuilder: (BuildContext buildContext, Animation<double> animation, Animation<double> secondaryAnimation) {
      final Widget pageChild = child ?? Builder(builder: builder);
      return SafeArea(
        child: Builder(builder: (BuildContext context) {
          return theme != null ? Theme(data: theme, child: pageChild) : pageChild;
        }),
      );
    },
    barrierDismissible: barrierDismissible,
    barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
    barrierColor: Colors.black54,
    transitionDuration: const Duration(milliseconds: 200),
    transitionBuilder: (context, animation1, animation2, child) {
      return _buildDialogTransitions(context, animation1, animation2, child, transitionType);
    },
    useRootNavigator: useRootNavigator,
    routeSettings: routeSettings,
  );
}

Widget _buildDialogTransitions(
    BuildContext context, Animation<double> animaton1, Animation<double> secondaryAnimation, Widget child, TransitionType type) {
  if (type == TransitionType.fade) {
    // 渐变效果
    return FadeTransition(
      // 从0开始到1
      opacity: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
        // 传入设置的动画
        parent: animaton1,
        // 设置效果,快进漫出   这里有很多内置的效果
        curve: Curves.fastOutSlowIn,
      )),
      child: child,
    );
  } else if (type == TransitionType.scale) {
    return ScaleTransition(
      scale: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(parent: animaton1, curve: Curves.fastOutSlowIn)),
      child: child,
    );
  } else if (type == TransitionType.rotation) {
    // 旋转加缩放动画效果
    return RotationTransition(
      turns: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
        parent: animaton1,
        curve: Curves.fastOutSlowIn,
      )),
      child: ScaleTransition(
        scale: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(parent: animaton1, curve: Curves.fastOutSlowIn)),
        child: child,
      ),
    );
  } else if (type == TransitionType.inFromLeft) {
    // 左右滑动动画效果
    return SlideTransition(
      position: Tween<Offset>(begin: Offset(-1.0, 0.0), end: Offset(0.0, 0.0))
          .animate(CurvedAnimation(parent: animaton1, curve: Curves.fastOutSlowIn)),
      child: child,
    );
  } else if (type == TransitionType.inFromRight) {
    return SlideTransition(
      position: Tween<Offset>(begin: Offset(1.0, 0.0), end: Offset(0.0, 0.0))
          .animate(CurvedAnimation(parent: animaton1, curve: Curves.fastOutSlowIn)),
      child: child,
    );
  } else if (type == TransitionType.inFromTop) {
    return SlideTransition(
      position: Tween<Offset>(begin: Offset(0.0, -1.0), end: Offset(0.0, 0.0))
          .animate(CurvedAnimation(parent: animaton1, curve: Curves.fastOutSlowIn)),
      child: child,
    );
  } else if (type == TransitionType.inFromBottom) {
    return SlideTransition(
      position: Tween<Offset>(begin: Offset(0.0, 1.0), end: Offset(0.0, 0.0))
          .animate(CurvedAnimation(parent: animaton1, curve: Curves.fastOutSlowIn)),
      child: child,
    );
  } else if (type == TransitionType.size) {
    return SizeTransition(
      child: child,
      sizeFactor: Tween<double>(begin: 0.1, end: 1.0).animate(CurvedAnimation(parent: animaton1, curve: Curves.linear)),
    );
  } else {
    return child;
  }
}

如果本文内容对您有用,记得点个赞吧!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268