J'ai 2 pages ( Page1
y Page2
) Pour naviguer entre eux, je dispose d'une fonction personnalisée de type PrimaryMenu
qui est le même pour les deux pages. Le site PrimaryMenu
est contenu dans BodyPage1
y BodyPage2
respectivement. Je dispose également d'un Header
widget. Les deux pages sont animées, tout comme l'en-tête.
Ce que je cherche à faire, c'est appuyer sur l'une des InkWell
l'animation est inversée sur la page actuelle, puis la nouvelle page est appelée. Je sais comment appeler la nouvelle page, je comprends à peu près comment utiliser GlobalKey
mais je commence à penser que cela ne peut pas être fait avec GlobalKey
. Je vais vous montrer ci-dessous les différents widgets que j'ai : lien dartpad au cas où https://dartpad.dev/88b8536ea7888b5621d7d80acdcd2887
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,
),
),
)
],
);
}
}
J'ai également créé un dartpad montrant ce que j'ai réussi à faire avec GlobalKey, mais je n'arrive à le faire fonctionner que si j'utilise une clé de type FloatingActionButton
en el Scaffold
- https://dartpad.dev/5979f44ecaa9cf2e22b4ce0cc9c23aa8
Désolé qu'il y ait beaucoup de code, j'ai essayé de le condenser autant que possible.