Hero Widget 动画效果 : Hero 通过动画从 源界面 运动到 目标界面 时 , 目标界面 透明度逐渐增加 , 淡入显示 ;
Hero 是界面的组成部分 , 在 源界面 和 目标界面 都存在该组件 ;
Hero 动画涉及到的 API 较多 ;
Hero 动画 tag 标识 : Hero 动画作用的组件在两个界面中都存在 , 给这两个 Hero 组件都设置相同的标识 , 通过该标识可以标识两个 Hero 组件之间进行动画过渡 ;
该 Hero 动画组件封装内容 :
代码示例 : 这里定义核心组件 Hero 组件 , 传入 tag 标识 , 与 Hero 动画作用的组件 ;
/// Hero 组件 , 跳转前后两个页面都有该组件
class HeroWidget extends StatelessWidget{
/// 构造方法
const HeroWidget({Key key, this.imageUrl, this.width, this.onTap}) : super(key: key);
/// Hero 动画之间关联的 ID , 通过该标识
/// 标识两个 Hero 组件之间进行动画过渡
/// 同时该字符串也是图片的 url 网络地址
final String imageUrl;
/// 点击后的回调事件
final VoidCallback onTap;
/// 宽度
final double width;
@override
Widget build(BuildContext context) {
return SizedBox(
width: width,
/// 这里定义核心组件 Hero 组件 , 传入 tag 标识 , 与 Hero 动画作用的组件
child: Hero(tag: imageUrl, child: Material(
color: Colors.transparent,
/// 按钮
child: InkWell(
/// 按钮点击事件
onTap: onTap,
child: Image.network(imageUrl, fit: BoxFit.contain,),
),
),),
);
}
}
创建一个 StatelessWidget 组件作为源页面 , 其中封装 HeroWidget 组件 , 作为显示的核心组件 , 传入一个 VoidCallback 方法 , 在该方法中跳转到目的界面 ;
class HeroAnimation extends StatelessWidget{
@override
Widget build(BuildContext context) {
// 时间膨胀系数 , 用于降低动画运行速度
timeDilation = 10.0;
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Hero 动画演示( 跳转前页面 )"),
),
body: Container(
color: Colors.white,
padding: EdgeInsets.all(20),
alignment: Alignment.bottomRight,
child: HeroWidget(
imageUrl: "https://img-blog.csdnimg.cn/20210329101628636.jpg",
width: 300,
// 点击事件 , 这里点击该组件后 , 跳转到新页面
onTap: (){
},
),
),
),
);
}
}
创建目的界面 : 这里直接在代码中创建 , 该界面中也封装了 HeroWidget 组件 , 其 tag 与源界面 HeroWidget 组件相同 , 这样就可以保证这两个界面互相跳转时 , 能触发 Hero 动画 ;
MaterialPageRoute(
builder: (context){
/// 跳转到的新界面再此处定义
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Hero 动画演示( 跳转后页面 )"),
),
body: Container(
color: Colors.white,
padding: EdgeInsets.all(20),
alignment: Alignment.topLeft,
child: HeroWidget(
imageUrl: "https://img-blog.csdnimg.cn/20210329101628636.jpg",
width: 100,
onTap: (){
/// 退出当前界面
Navigator.of(context).pop();
},
),
),
),
);
}
)
使用 Navigator 进行页面跳转 , 这个页面直接在方法中创建出来 ;
Navigator.of(context).push(
MaterialPageRoute(
builder: (context){
/// 跳转到的新界面再此处定义
return MaterialApp(
home: Scaffold(
),
);
}
)
);
如果出现页面跳转错误 , 参考 【错误记录】Flutter 界面跳转报错 ( Navigator operation requested with a context that does not include a Naviga ) 解决 ;
完整代码示例 :
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart' show timeDilation;
void main() {
runApp(
MaterialApp(
home: HeroAnimation(),
)
);
}
/// Hero 组件 , 跳转前后两个页面都有该组件
class HeroWidget extends StatelessWidget{
/// 构造方法
const HeroWidget({Key key, this.imageUrl, this.width, this.onTap}) : super(key: key);
/// Hero 动画之间关联的 ID , 通过该标识
/// 标识两个 Hero 组件之间进行动画过渡
/// 同时该字符串也是图片的 url 网络地址
final String imageUrl;
/// 点击后的回调事件
final VoidCallback onTap;
/// 宽度
final double width;
@override
Widget build(BuildContext context) {
return SizedBox(
width: width,
/// 这里定义核心组件 Hero 组件 , 传入 tag 标识 , 与 Hero 动画作用的组件
child: Hero(tag: imageUrl, child: Material(
color: Colors.transparent,
/// 按钮
child: InkWell(
/// 按钮点击事件
onTap: onTap,
child: Image.network(imageUrl, fit: BoxFit.contain,),
),
),),
);
}
}
class HeroAnimation extends StatelessWidget{
@override
Widget build(BuildContext context) {
// 时间膨胀系数 , 用于降低动画运行速度
timeDilation = 10.0;
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Hero 动画演示( 跳转前页面 )"),
),
body: Container(
color: Colors.white,
padding: EdgeInsets.all(20),
alignment: Alignment.bottomRight,
child: HeroWidget(
imageUrl: "https://img-blog.csdnimg.cn/20210329101628636.jpg",
width: 300,
// 点击事件 , 这里点击该组件后 , 跳转到新页面
onTap: (){
print("点击事件触发, 切换到新界面");
Navigator.of(context).push(
MaterialPageRoute(
builder: (context){
/// 跳转到的新界面再此处定义
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Hero 动画演示( 跳转后页面 )"),
),
body: Container(
color: Colors.white,
padding: EdgeInsets.all(20),
alignment: Alignment.topLeft,
child: HeroWidget(
imageUrl: "https://img-blog.csdnimg.cn/20210329101628636.jpg",
width: 100,
onTap: (){
/// 退出当前界面
Navigator.of(context).pop();
},
),
),
),
);
}
)
);
},
),
),
),
);
}
}
运行效果 :
参考资料 :
重要的专题 :
博客源码下载 :