我想在主屏幕上为图像实现英雄动画,同时在对话框的内容中呈现与对话框相同图像的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'),
),
),
),
);
},
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
NIR*_*TEL 11
你可以你 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'),
),
),
);
}
)
)
Run Code Online (Sandbox Code Playgroud)
在此处演示示例代码。
Col*_*son 10
英雄转换仅在的两个实例之间转换时启用PageRoute。因此,如果您想使用现有Hero系统,则可能应该使用PageRoute。
AlertDialog您可以尝试使用全屏对话框,而不用按下,即可以:
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'),
),
),
);
}
));
Run Code Online (Sandbox Code Playgroud)
如果您需要半透明的障碍,则可以扩展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,
),
],
),
);
},
),
);
},
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
根据对话框的大小和您的英雄所处的位置,Hero当第二个Hero动画完成定位后,您也许可以看到原来的内容重新出现在对话框下面。如果这让您感到困扰,则可以堆叠图像的两份副本,而最上面的一个为Hero,或者可以触发动画以隐藏原始图像Hero(也许使用AnimatedCrossFade),直到关闭对话框。
另一个选择是您可以自己实现动画,而不是使用现有Hero系统。您可能需要阅读动画文档,并可能复制了heroes.dart的片段。
| 归档时间: |
|
| 查看次数: |
2444 次 |
| 最近记录: |