题记
—— 执剑天涯,从你的点滴积累开始,所及之处,必精益求精,即是折腾每一天。
** | 你可能需要 |
---|---|
CSDN | 网易云课堂教程 |
掘金 | EDU学院教程 |
知乎 | Flutter系列文章 |
本文章通过 OpenContainer 结合列表 ListView来实现页面的径向过渡动画,最终实现现的效果如下:
引入依赖:
# Material motion 规范的预构建动画
animations: ^1.1.1
整个页面通过ListView来构建:
import 'dart:ui';
import 'package:animations/animations.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class OpenContainerPage extends StatefulWidget {
@override
_FlashAnimationPageState createState() => _FlashAnimationPageState();
}
class _FlashAnimationPageState extends State<OpenContainerPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("OpenContainer过渡"),
),
backgroundColor: Colors.grey[200],
///列表
body: ListView.builder(
///构建每个列表的显示的Widget
itemBuilder: (BuildContext context, int index) {
return buildOpenContainer(index);
},
itemCount: 10,
),
);
}
/// 列表中的每个条目的Widget
/// [index] 列表条目对应的索引
buildContentWidget(int index) {
///手势事件点击跳转
return GestureDetector(
///条目显示的一张图片
child: buildShowItemContainer(),
onTap: () {
///点击打开新的页面
Navigator.of(context)
.push(MaterialPageRoute(builder: (BuildContext context) {
return Item2Page();
}));
});
}
/// lib/code23/main_data2336.dart
/// 列表中的每个条目的Widget
/// [index] 列表条目对应的索引
buildOpenContainerItem(int index) {
return OpenContainer(
///将要打开的页面
openBuilder:
(BuildContext context, void Function({Object returnValue}) action) {
return Item2Page();
},
///现在显示的页面
closedBuilder: (BuildContext context, void Function() action) {
///条目显示的一张图片
return buildShowItemContainer();
},
);
}
... ... ...
}
列表中显示的Item构建如下:
Container buildShowItemContainer() {
return Container(
color: Colors.blueGrey,
///边距设置
margin: EdgeInsets.only(top: 8),
child: Image.asset(
"assets/images/2.0x/banner4.webp",
fit: BoxFit.fill,
),
);
}
将要打开的页面构建如下:
class Item2Page extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _Item2PageState();
}
}
class _Item2PageState extends State<Item2Page> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0.0,
title: Text("页面二"),
),
///页面二中的Hero
body: InkWell(
onTap: () {
Navigator.of(context).pop(true);
},
child: Image.asset(
"assets/images/2.0x/banner1.webp",
fit: BoxFit.fill,
),
),
);
}
}
详细属性配制如下:
buildOpenContainer() {
///容器转换路由
return OpenContainer(
///过渡的动画类型
transitionType: ContainerTransitionType.fade,
///过渡时间
transitionDuration: Duration(milliseconds: 3000),
///closedBuilder配置的Widget的背景色
closedColor: Colors.white,
///阴影高度
closedElevation: 2,
///边框样式
closedShape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10))),
///默认显示的Widget
closedBuilder: (BuildContext context, void Function() action) {
///条目显示的一张图片
return buildShowItemContainer();
},
///点击打开的页面
openBuilder:
(BuildContext context, void Function({Object returnValue}) action) {
return Item2Page();
},
///openBuilder配置的Widget的背景色
openColor: Colors.blue,
openElevation: 1.0,
openShape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10))),
///从第二个页面中返回时的回调
///参数 value就是上一个页面回传的参数
onClosed: (value) {
print("onClosed $value");
},
);
}
完结