I am trying to create a Material NavigationRail that, with the click of a button on the rail, shows a drawer with secondary destinations in my app. I have a Scaffold that as a body has a Row containing the NavigationRail and a Stack. The Stack contains the actual content of my homepage as well as the drawer, but only when the button has been clicked (I use riverpod).
I want to animate the drawer in and out on button clicks, but the drawer appears on top of the NavigationRail. How do I keep the rail in front of the drawer? If I include it in the stack, the content and the drawer are shifted to the left, behind the rail, so that does not work.
Currently, the animation looks like this:
I made a Dartpad that reproduces the behaviour: DartPad
CodePudding user response:
You can use only Stack
with AnimatedPosition widget.
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
bool drawerOpen = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
AnimatedPositioned(
duration: const Duration(milliseconds: 200),
left: drawerOpen ? 64 : -300,
width: 300,
top: 0,
bottom: 0,
child: const SizedBox(
height: double.infinity,
width: 300,
child: ColoredBox(color: Colors.blue),
),
),
Positioned(
left: 0,
top: 0,
bottom: 0,
width: 64,
child: NavigationRail(
backgroundColor: Colors.deepPurple,
leading: IconButton(
icon: const Icon(Icons.menu),
onPressed: () {
setState(() {
drawerOpen = !drawerOpen;
});
},
),
destinations: const [
NavigationRailDestination(
icon: Icon(Icons.abc), label: Text("A")),
NavigationRailDestination(
icon: Icon(Icons.ac_unit), label: Text("B"))
],
selectedIndex: 1,
),
),
],
));
}
}