Flutter 从第三个小部件(不是父小部件)调用两个不同小部件中的动画
我有两个页面(Flutter 从第三个小部件(不是父小部件)调用两个不同小部件中的动画,flutter,dart,flutter-web,flutter-animation,Flutter,Dart,Flutter Web,Flutter Animation,我有两个页面(Page1和Page2)在它们之间导航我有一个自定义的主菜单小部件,这两个页面都是相同的。主菜单分别包含在BodyPage1和BodyPage2中。我还有一个自定义的标题小部件。两个页面都有动画,页眉也有动画 我想做的是按下InkWell小部件中的一个,然后动画在当前页面上反转,然后调用新页面。我知道如何调用新页面,我对如何使用GlobalKey有大致的了解,但我开始认为这不能用GlobalKey完成。下面我将展示我拥有的各个小部件:dartpad链接以防万一- 类头扩展State
Page1
和Page2
)在它们之间导航我有一个自定义的主菜单
小部件,这两个页面都是相同的。主菜单
分别包含在BodyPage1
和BodyPage2
中。我还有一个自定义的标题
小部件。两个页面都有动画,页眉也有动画
我想做的是按下InkWell
小部件中的一个,然后动画在当前页面上反转,然后调用新页面。我知道如何调用新页面,我对如何使用GlobalKey
有大致的了解,但我开始认为这不能用GlobalKey
完成。下面我将展示我拥有的各个小部件:dartpad链接以防万一-
类头扩展StatefulWidget{
@凌驾
_HeaderState createState()=>U HeaderState();
}
类_HeaderState使用SingleTickerProviderStateMixin扩展状态{
动画控制器转换动画;
@凌驾
void initState(){
super.initState();
transitionAnimation=动画控制器(
持续时间:常数持续时间(秒数:3),
vsync:这个,,
);
transitionAnimation.forward();
}
@凌驾
小部件构建(构建上下文){
返回容器(
颜色:颜色(0x88DDDD),
高度:MediaQuery.of(context).size.height,
宽度:MediaQuery.of(context).size.width,
孩子:排(
crossAxisAlignment:crossAxisAlignment.center,
儿童:[
大小盒子(
宽度:8,
),
动画生成器(
动画:过渡动画,
生成器:(上下文,子对象){
返回幻灯片转换(
位置:吐温(
开始:常量偏移(-2,0),结束:常量偏移(0,0))
.动画(曲线动画)(
曲线:常数间隔(0,0.3,
曲线:曲线。缓速返回),
父项:转换(动画),
孩子:孩子,
);
},
子:容器(
身高:100,
宽度:MediaQuery.of(context).size.width*0.135,
颜色:颜色。粉红色,
),
),
扩大(
子级:容器(),
),
容器(
宽度:100,
身高:50,
颜色:颜色,紫色,
),
大小盒子(
宽度:8,
),
容器(
身高:50,
宽度:50,
颜色:颜色。琥珀色,
),
大小盒子(
宽度:8,
)
],
));
}
}
class Page1扩展了StatefulWidget{
@凌驾
_Page1State createState();
}
类_Page1State扩展状态{
@凌驾
小部件构建(构建上下文){
返回脚手架(
extendedBodyBehindAppBar:true,
appBar:首选大小(
preferredSize:Size(MediaQuery.of(context).Size.width,120),
子项:头(),
),
正文:BodyPage1(),
);
}
}
class PrimaryMenu扩展StatefulWidget{
@凌驾
_PrimaryMenuState createState()=>\u PrimaryMenuState();
}
类_primarymenstate扩展了状态{
@凌驾
小部件构建(构建上下文){
返回容器(
高度:MediaQuery.of(context).size.height,
宽度:MediaQuery.of(context).size.width*0.15,
颜色:颜色,蓝色,
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
容器(
身高:40,
宽度:MediaQuery.of(context).size.width*0.135,
颜色:颜色。灰色,
孩子:InkWell(
onTap:(){
打印('1');
导航器。推(
上下文
材料路线(
生成器:(上下文)=>Page1(),
));
},
)),
尺寸箱(高度:16),
容器(
身高:40,
宽度:MediaQuery.of(context).size.width*0.135,
颜色:颜色,黑色,
孩子:InkWell(
onTap:(){
印刷品(‘2’);
导航器。推(
上下文
材料路线(
生成器:(上下文)=>Page2(),
));
},
)),
],
));
}
}
class BodyPage1扩展了StatefulWidget{
@凌驾
_BodyPage1State createState()=>\u BodyPage1State();
}
类_BodyPage1State扩展状态
使用SingleTickerProviderStateMixin{
动画控制器转换动画;
@凌驾
void initState(){
super.initState();
transitionAnimation=动画控制器(
持续时间:常数持续时间(秒数:3),
vsync:这个,,
);
transitionAnimation.forward();
}
@凌驾
小部件构建(构建上下文){
返回行(
儿童:[
动画生成器(
动画:过渡动画,
生成器:(上下文,子对象){
返回幻灯片转换(
位置:吐温(
开始:常量偏移(-2,0),结束:常量偏移(0,0))
.动画(曲线动画)(
曲线:
常数间隔(0,0.3,曲线:曲线。缓变返回),
父项:转换(动画),
孩子:孩子,
);
},
子项:PrimaryMenu()),
动画生成器(
动画:过渡动画,
class Header extends StatefulWidget {
@override
_HeaderState createState() => _HeaderState();
}
class _HeaderState extends State<Header> with SingleTickerProviderStateMixin {
AnimationController transitionAnimation;
@override
void initState() {
super.initState();
transitionAnimation = AnimationController(
duration: const Duration(seconds: 3),
vsync: this,
);
transitionAnimation.forward();
}
@override
Widget build(BuildContext context) {
return Container(
color: Color(0x88dddddd),
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
width: 8,
),
AnimatedBuilder(
animation: transitionAnimation,
builder: (context, child) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(-2, 0), end: const Offset(0, 0))
.animate(CurvedAnimation(
curve: const Interval(0, 0.3,
curve: Curves.easeInOutBack),
parent: transitionAnimation)),
child: child,
);
},
child: Container(
height: 100,
width: MediaQuery.of(context).size.width * 0.135,
color: Colors.pink,
),
),
Expanded(
child: Container(),
),
Container(
width: 100,
height: 50,
color: Colors.purple,
),
SizedBox(
width: 8,
),
Container(
height: 50,
width: 50,
color: Colors.amber,
),
SizedBox(
width: 8,
)
],
));
}
}
class Page1 extends StatefulWidget {
@override
_Page1State createState() => _Page1State();
}
class _Page1State extends State<Page1> {
@override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: PreferredSize(
preferredSize: Size(MediaQuery.of(context).size.width, 120),
child: Header(),
),
body: BodyPage1(),
);
}
}
class PrimaryMenu extends StatefulWidget {
@override
_PrimaryMenuState createState() => _PrimaryMenuState();
}
class _PrimaryMenuState extends State<PrimaryMenu> {
@override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width * 0.15,
color: Colors.blue,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 40,
width: MediaQuery.of(context).size.width * 0.135,
color: Colors.grey,
child: InkWell(
onTap: () {
print('1');
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Page1(),
));
},
)),
SizedBox(height: 16),
Container(
height: 40,
width: MediaQuery.of(context).size.width * 0.135,
color: Colors.black,
child: InkWell(
onTap: () {
print('2');
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Page2(),
));
},
)),
],
));
}
}
class BodyPage1 extends StatefulWidget {
@override
_BodyPage1State createState() => _BodyPage1State();
}
class _BodyPage1State extends State<BodyPage1>
with SingleTickerProviderStateMixin {
AnimationController transitionAnimation;
@override
void initState() {
super.initState();
transitionAnimation = AnimationController(
duration: const Duration(seconds: 3),
vsync: this,
);
transitionAnimation.forward();
}
@override
Widget build(BuildContext context) {
return Row(
children: [
AnimatedBuilder(
animation: transitionAnimation,
builder: (context, child) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(-2, 0), end: const Offset(0, 0))
.animate(CurvedAnimation(
curve:
const Interval(0, 0.3, curve: Curves.easeInOutBack),
parent: transitionAnimation)),
child: child,
);
},
child: PrimaryMenu()),
AnimatedBuilder(
animation: transitionAnimation,
builder: (context, child) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(-2, 0), end: const Offset(0, 0))
.animate(CurvedAnimation(
curve: const Interval(0.3, 1, curve: Curves.easeIn),
parent: transitionAnimation)),
child: child);
},
child: Padding(
padding: EdgeInsets.only(top: 140, left: 20, right: 20, bottom: 20),
child: Container(
height: MediaQuery.of(context).size.height - 140,
width: (MediaQuery.of(context).size.width * .85) - 40,
color: Colors.grey,
),
),
)
],
);
}
}
class Page2 extends StatefulWidget {
@override
_Page2State createState() => _Page2State();
}
class _Page2State extends State<Page2> {
@override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: PreferredSize(
preferredSize: Size(MediaQuery.of(context).size.width, 120),
child: Header(),
),
body: BodyPage2(),
);
}
}
class BodyPage2 extends StatefulWidget {
@override
_BodyPage2State createState() => _BodyPage2State();
}
class _BodyPage2State extends State<BodyPage2>
with SingleTickerProviderStateMixin {
AnimationController transitionAnimation;
@override
void initState() {
super.initState();
transitionAnimation = AnimationController(
duration: const Duration(seconds: 3),
vsync: this,
);
transitionAnimation.forward();
}
@override
Widget build(BuildContext context) {
return Row(
children: [
AnimatedBuilder(
animation: transitionAnimation,
builder: (context, child) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(-2, 0), end: const Offset(0, 0))
.animate(CurvedAnimation(
curve:
const Interval(0, 0.3, curve: Curves.easeInOutBack),
parent: transitionAnimation)),
child: child,
);
},
child: PrimaryMenu()),
AnimatedBuilder(
animation: transitionAnimation,
builder: (context, child) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(-2, 0), end: const Offset(0, 0))
.animate(CurvedAnimation(
curve: const Interval(0.3, 1, curve: Curves.easeIn),
parent: transitionAnimation)),
child: child);
},
child: Padding(
padding: EdgeInsets.only(top: 140, left: 20, right: 20, bottom: 20),
child: Container(
height: MediaQuery.of(context).size.height - 140,
width: (MediaQuery.of(context).size.width * .85) - 40,
color: Colors.black,
),
),
)
],
);
}
}
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(visualDensity: VisualDensity.adaptivePlatformDensity),
debugShowCheckedModeBanner: false,
home: Page1(),
);
}
}
class Header extends StatefulWidget {
@override
_HeaderState createState() => _HeaderState();
}
class _HeaderState extends State<Header> with SingleTickerProviderStateMixin {
AnimationController transitionAnimation;
@override
void initState() {
super.initState();
transitionAnimation = AnimationController(
duration: const Duration(seconds: 3),
vsync: this,
);
transitionAnimation.forward();
}
@override
Widget build(BuildContext context) {
return Container(
color: const Color(0x88dddddd),
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(
width: 8,
),
AnimatedBuilder(
animation: transitionAnimation,
builder: (context, child) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(-2, 0), end: const Offset(0, 0))
.animate(CurvedAnimation(
curve: const Interval(0, 0.3,
curve: Curves.easeInOutBack),
parent: transitionAnimation)),
child: child,
);
},
child: Container(
height: 100,
width: MediaQuery.of(context).size.width * 0.135,
color: Colors.pink,
),
),
Expanded(
child: Container(),
),
Container(
width: 100,
height: 50,
color: Colors.purple,
),
const SizedBox(
width: 8,
),
Container(
height: 50,
width: 50,
color: Colors.amber,
),
const SizedBox(
width: 8,
)
],
));
}
}
class Page1 extends StatefulWidget {
@override
_Page1State createState() => _Page1State();
}
class _Page1State extends State<Page1> {
@override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: PreferredSize(
preferredSize: Size(MediaQuery.of(context).size.width, 120),
child: Header(),
),
body: BodyPage1(),
);
}
}
class PrimaryMenu extends StatefulWidget {
final AnimationController controller;
const PrimaryMenu({Key key, this.controller}) : super(key: key);
@override
_PrimaryMenuState createState() => _PrimaryMenuState();
}
class _PrimaryMenuState extends State<PrimaryMenu> {
@override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width * 0.15,
color: Colors.blue,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 40,
width: MediaQuery.of(context).size.width * 0.135,
color: Colors.grey,
child: InkWell(
onTap: () async {
print('1');
await widget.controller
.reverse()
.then((value) => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Page1(),
)));
},
)),
const SizedBox(height: 16),
Container(
height: 40,
width: MediaQuery.of(context).size.width * 0.135,
color: Colors.black,
child: InkWell(
onTap: () async {
print('2');
await widget.controller
.reverse()
.then((value) => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Page2(),
)));
},
)),
],
));
}
}
class BodyPage1 extends StatefulWidget {
@override
_BodyPage1State createState() => _BodyPage1State();
}
class _BodyPage1State extends State<BodyPage1>
with SingleTickerProviderStateMixin {
AnimationController transitionAnimation;
@override
void initState() {
super.initState();
transitionAnimation = AnimationController(
duration: const Duration(seconds: 3),
vsync: this,
);
transitionAnimation.forward();
}
@override
Widget build(BuildContext context) {
return Row(
children: [
AnimatedBuilder(
animation: transitionAnimation,
builder: (context, child) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(-2, 0), end: const Offset(0, 0))
.animate(CurvedAnimation(
curve:
const Interval(0, 0.3, curve: Curves.easeInOutBack),
parent: transitionAnimation)),
child: child,
);
},
child: PrimaryMenu(
controller: transitionAnimation,
)),
AnimatedBuilder(
animation: transitionAnimation,
builder: (context, child) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(-2, 0), end: const Offset(0, 0))
.animate(CurvedAnimation(
curve: const Interval(0.3, 1, curve: Curves.easeIn),
parent: transitionAnimation)),
child: child);
},
child: Padding(
padding: const EdgeInsets.only(
top: 140, left: 20, right: 20, bottom: 20),
child: Container(
height: MediaQuery.of(context).size.height - 140,
width: (MediaQuery.of(context).size.width * .85) - 40,
color: Colors.grey,
),
),
)
],
);
}
}
class Page2 extends StatefulWidget {
@override
_Page2State createState() => _Page2State();
}
class _Page2State extends State<Page2> {
@override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: PreferredSize(
preferredSize: Size(MediaQuery.of(context).size.width, 120),
child: Header(),
),
body: BodyPage2(),
);
}
}
class BodyPage2 extends StatefulWidget {
@override
_BodyPage2State createState() => _BodyPage2State();
}
class _BodyPage2State extends State<BodyPage2>
with SingleTickerProviderStateMixin {
AnimationController transitionAnimation;
@override
void initState() {
super.initState();
transitionAnimation = AnimationController(
duration: const Duration(seconds: 3),
vsync: this,
);
transitionAnimation.forward();
}
@override
Widget build(BuildContext context) {
return Row(
children: [
AnimatedBuilder(
animation: transitionAnimation,
builder: (context, child) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(-2, 0), end: const Offset(0, 0))
.animate(CurvedAnimation(
curve:
const Interval(0, 0.3, curve: Curves.easeInOutBack),
parent: transitionAnimation)),
child: child,
);
},
child: PrimaryMenu(
controller: transitionAnimation,
)),
AnimatedBuilder(
animation: transitionAnimation,
builder: (context, child) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(-2, 0), end: const Offset(0, 0))
.animate(CurvedAnimation(
curve: const Interval(0.3, 1, curve: Curves.easeIn),
parent: transitionAnimation)),
child: child);
},
child: Padding(
padding: const EdgeInsets.only(
top: 140, left: 20, right: 20, bottom: 20),
child: Container(
height: MediaQuery.of(context).size.height - 140,
width: (MediaQuery.of(context).size.width * .85) - 40,
color: Colors.black,
),
),
)
],
);
}
}