【发布时间】:2022-01-24 01:28:53
【问题描述】:
有很多小部件,例如 Visibility 或 AnimatedOpacity,但我希望小部件能够以流畅的动画出现并增长到其完整大小,从而将围绕它的其他 Column 的子项移开。
AnimatedContainer 会很酷,但我不想从父级设置子级的约束(例如高度)(然后我必须在每次 UI 更改时测试并设置正确的大小)。
【问题讨论】:
有很多小部件,例如 Visibility 或 AnimatedOpacity,但我希望小部件能够以流畅的动画出现并增长到其完整大小,从而将围绕它的其他 Column 的子项移开。
AnimatedContainer 会很酷,但我不想从父级设置子级的约束(例如高度)(然后我必须在每次 UI 更改时测试并设置正确的大小)。
【问题讨论】:
使用英雄动画查看此链接了解:
https://docs.flutter.dev/development/ui/animations/hero-animations
例子:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/first',
routes: {
'/first': (context) => FirstScreen(),
'/second': (context) => SecondScreen(),
},
);
}
}
class FirstScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Screen'),
),
body: Padding(
padding: EdgeInsets.all(15),
child: Column(
children: [
Hero(
tag: "HeroOne",
child: Icon(
Icons.image,
size: 50.0,
),
),
ElevatedButton(
child: Text('Go to second screen'),
onPressed: () {
Navigator.push(context, CustomPageRoute(SecondScreen()));
},
),
],
),
),
);
}
}
class SecondScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Screen"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Hero(
tag: "HeroOne",
child: Icon(
Icons.image,
size: 150.0,
),
),
ElevatedButton(
child: Text('Back to first screen!'),
onPressed: () {
Navigator.pop(context);
},
),
],
)
),
);
}
}
class CustomPageRoute<T> extends PageRoute<T> {
final Widget child;
CustomPageRoute(this.child);
@override
Color get barrierColor => Colors.black;
@override
String get barrierLabel => '';
@override
bool get maintainState => true;
@override
Duration get transitionDuration => Duration(seconds: 2);
@override
Widget buildPage({1}
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation
) {
return FadeTransition(
opacity: animation,
child: child,
);
}
}
更多检查:
https://www.woolha.com/tutorials/flutter-creating-hero-transition-examples
【讨论】:
在针对我自己的问题进行更多研究时,我发现 AnimatedSize 小部件可以满足我的需要:
要动态显示和隐藏具有大小动画的小部件,只需将其包装在 AnimatedSize() 中并为其指定持续时间。
https://api.flutter.dev/flutter/widgets/AnimatedSize-class.html
【讨论】: