Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Dart 带有AlertDialog的英雄动画_Dart_Flutter - Fatal编程技术网

Dart 带有AlertDialog的英雄动画

Dart 带有AlertDialog的英雄动画,dart,flutter,Dart,Flutter,我想在主屏幕上为一个图像实现一个英雄动画,同时在对话框内容中呈现一个具有相同图像的AlertDialog小部件 我希望演示文稿如下面的屏幕截图所示。当我点击左下角的图像时,我想要英雄动画和图像的插入预览,以及一个可以点击关闭的透明覆盖 下面的代码不执行英雄动画 class AlertDialogTest extends StatelessWidget { @override Widget build(BuildContext context) { return new Mate

我想在主屏幕上为一个图像实现一个英雄动画,同时在对话框内容中呈现一个具有相同图像的AlertDialog小部件

我希望演示文稿如下面的屏幕截图所示。当我点击左下角的图像时,我想要英雄动画和图像的插入预览,以及一个可以点击关闭的透明覆盖

下面的代码不执行英雄动画

class AlertDialogTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Material(
      child: new InkWell(
        child: new Hero(
          tag: "preview",
          child: new Container(
            alignment: FractionalOffset.bottomLeft,
            child: new Image(
              image: new AssetImage('assets/images/theater.png'),
            ),
          ),
        ),
        onTap: () {
          showDialog(
            context: context,
            child: new AlertDialog(
              content: new Hero(
                tag: "preview",
                child: new Image(
                  image: new AssetImage('assets/images/theater.png'),
                ),
              ),
            ),
          );
        },
      ),
    );
  }
}

英雄转换仅在
PageRoute
的两个实例之间启用。因此,如果您想利用现有的
Hero
系统,您可能应该使用
PageRoute

您可以尝试全屏对话框,而不是按
警报对话框

Navigator.push(context, new MaterialPageRoute(
  fullscreenDialog: true,
  builder: (BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Dialog'),
      ),
      body: new Hero(
        tag: "preview",
        child: new Image(
          image: new AssetImage('assets/images/theater.png'),
        ),
      ),
    );
  }
));
如果需要半透明屏障,可以扩展
PageRoute
,使其更像对话框

下面是一些实现上述动画的代码

import 'package:flutter/material.dart';

void main() {
  runApp(new MaterialApp(
    home: new HomePage(),
  ));
}

class HeroDialogRoute<T> extends PageRoute<T> {
  HeroDialogRoute({ this.builder }) : super();

  final WidgetBuilder builder;

  @override
  bool get opaque => false;

  @override
  bool get barrierDismissible => true;

  @override
  Duration get transitionDuration => const Duration(milliseconds: 300);

  @override
  bool get maintainState => true;

  @override
  Color get barrierColor => Colors.black54;

  @override
  Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
    return new FadeTransition(
      opacity: new CurvedAnimation(
        parent: animation,
        curve: Curves.easeOut
      ),
      child: child
    );
  }

  @override
  Widget buildPage(BuildContext context, Animation<double> animation,
    Animation<double> secondaryAnimation) {
    return builder(context);
  }

}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Hero demo'),
      ),
      body: new Align(
        alignment: FractionalOffset.center,
        child: new Card(
          child: new Hero(
            tag: 'developer-hero',
            child: new Container(
              width: 300.0,
              height: 300.0,
              child: new FlutterLogo(),
            ),
          ),
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        child: new Icon(Icons.developer_mode),
        onPressed: () {
          Navigator.push(
            context,
            new HeroDialogRoute(
              builder: (BuildContext context) {
                return new Center(
                  child: new AlertDialog(
                    title: new Text('You are my hero.'),
                    content: new Container(
                      child: new Hero(
                        tag: 'developer-hero',
                        child: new Container(
                          height: 200.0,
                          width: 200.0,
                          child: new FlutterLogo(),
                        ),
                      ),
                    ),
                    actions: <Widget>[
                      new FlatButton(
                        child: new Text('RAD!'),
                        onPressed: Navigator
                          .of(context)
                          .pop,
                      ),
                    ],
                  ),
                );
              },
            ),
          );
        },
      ),
    );
  }
}
导入“包装:颤振/材料.省道”;
void main(){
runApp(新材料)PP(
主页:新主页(),
));
}
类扩展了PageRoute{
HeroDialogRoute({this.builder}):super();
最终WidgetBuilder;
@凌驾
bool get不透明=>false;
@凌驾
bool get barrierDismissible=>true;
@凌驾
Duration get transitionDuration=>const Duration(毫秒:300);
@凌驾
bool get maintaintState=>true;
@凌驾
颜色获取barrierColor=>Colors.black54;
@凌驾
小部件构建转换(构建上下文上下文、动画、动画辅助动画、小部件子级){
返回新的FadeTransition(
不透明度:新的曲线动画(
家长:动画,
曲线:Curves.easeOut
),
孩子:孩子
);
}
@凌驾
小部件构建页面(构建上下文、动画、,
动画(二级动画){
返回生成器(上下文);
}
}
类主页扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
归还新脚手架(
appBar:新的appBar(
标题:新文本(“英雄演示”),
),
正文:新对齐(
对齐:分馏loffset.center,
孩子:新卡(
孩子:新英雄(
标签:“开发者英雄”,
子容器:新容器(
宽度:300.0,
高度:300.0,
子项:新徽标(),
),
),
),
),
floatingActionButton:新的floatingActionButton(
子:新图标(图标。开发者模式),
已按下:(){
导航器。推(
上下文
新路线(
生成器:(BuildContext上下文){
返回新中心(
子:新建警报对话框(
标题:新文本(“你是我的英雄”),
内容:新容器(
孩子:新英雄(
标签:“开发者英雄”,
子容器:新容器(
高度:200.0,
宽度:200.0,
子项:新徽标(),
),
),
),
行动:[
新扁平按钮(
子:新文本('RAD!'),
onPressed:导航器
.of(上下文)
.爸爸,
),
],
),
);
},
),
);
},
),
);
}
}
根据对话框大小和英雄所在的位置,当第二个
英雄
完成动画设置到位后,您可能会看到原始的
英雄
再次出现在对话框下方。如果这让您感到困扰,您可以堆叠图像的两个副本,其中只有顶部的一个是
英雄
,或者可以触发动画以隐藏原始
英雄
(可能使用
动画交叉淡入
),直到对话框关闭


另一个选择是,您可以自己实现动画,而不是使用现有的
Hero
系统。您可能需要阅读并可能复制的部分。

您可以使用PageRouteBuilder

将onTap()代码替换为以下代码

Navigator.of(context).push(
    new PageRouteBuilder(
        opaque: false,
        barrierDismissible:true,
        pageBuilder: (BuildContext context, _, __) {
            return Container(
                new Hero(
                    tag: "preview",
                    child: new Image(
                        image: new AssetImage('assets/images/theater.png'),
                    ),
                ),
            );
        }
    )
)

这是示例代码。

谢谢。我已经编辑了我的帖子,并添加了我的目标演示文稿的截图。我不确定如何编辑您的样本以包含透明覆盖,或者这是否可能。编辑我的答案以解释如何使用半透明覆盖。这有点棘手,因为你可能可以同时看到两位英雄!很好用!HeroDialogRoute中的一个小错误:barrierDismissable->barrierDismissable。谢谢我修正了打字错误。谢谢这是一个简单的解决方案