如何使用flutter抽屉在同一页面上浏览视图



我将屏幕分成2部分。菜单在左边,菜单内容在右边。单击左侧菜单时,如何在右侧屏幕上显示内容?也就是说,我希望菜单内容显示在屏幕右侧,而不转到新页面。

SideMenu.art

class SideMenu extends StatefulWidget {
const SideMenu({Key? key}) : super(key: key);
@override
State<SideMenu> createState() => _SideMenuState();
}
class _SideMenuState extends State<SideMenu> {
@override
Widget build(BuildContext context) {
return Drawer(
child: SingleChildScrollView(
child: Column(
children: [
DrawerHeader(
child: Image.asset(
'images/Logomail4.png',
)),
DrawerListTile(
title: 'Home',
svgSrc: 'assets/icons/home.svg',
press: () {

},
),
DrawerListTile(
title: 'Home1',
svgSrc: 'assets/icons/Contour.svg',
press: () {

},
),
DrawerListTile(
title: 'Home2',
svgSrc: 'assets/icons/business.svg',
press: () {},
),
DrawerListTile(
title: 'Home3',
svgSrc: 'assets/icons/positions.svg',
press: () {},
),
DrawerListTile(
title: 'Exit',
svgSrc: 'assets/icons/exit.svg',
press: () async {
final shouldLogOut = await showLogOutDialog(context);
if (shouldLogOut) {
await AuthService.firebase().loguOut();
// ignore: use_build_context_synchronously
Navigator.of(context)
.pushNamedAndRemoveUntil(loginRoute, (route) => false);
}
},
)
],
),
),
);
}
}
class DrawerListTile extends StatelessWidget {
const DrawerListTile({
Key? key,
required this.title,
required this.svgSrc,
required this.press,
}) : super(key: key);
final String title, svgSrc;
final VoidCallback press;
@override
Widget build(BuildContext context) {
return ListTile(
horizontalTitleGap: 0.0,
onTap: press,
leading: SvgPicture.asset(
svgSrc,
color: Colors.grey,
height: 16,
),
title: Text(title, style: const TextStyle(color: Colors.grey)),
);
}
}
Future<bool> showLogOutDialog(BuildContext context) {
return showDialog<bool>(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Sign out'),
content: const Text('Are you sure you want to sign out?'),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(false);
},
child: const Text('Cancel')),
TextButton(
onPressed: () {
Navigator.of(context).pop(true);
},
child: const Text('Log out')),
],
);
},
).then((value) => value ?? false);
}

MainScreen.dart

class MainScreen extends StatefulWidget {
const MainScreen({Key? key}) : super(key: key);
@override
State<MainScreen> createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: const SideMenu(),
body: SafeArea(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Expanded(
// default flex = 1
// and it takes 1/6 part of the screen
child: SideMenu(),
),
const Expanded(
// It takes 5/6 part of the screen
flex: 5,
child: DashboardPage(),
),
],
),
),
);
}
}

您可以声明一个全局ValueNotifier<int>来存储索引,并使用ValueListenableBuilder<int>DashboardPage屏幕中侦听索引更改。

ValueNotifier<int> currentIndex = ValueNotifier<int>(0);
class DashboardPage extends StatelessWidget {
const DashboardPage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: ValueListenableBuilder<int>(valueListenable: currentIndex, builder: (ctx, currentIndex, child) {
if (currentIndex == 0) {
return Home1();
}
return Home3(); // default case
}),
);
}
}

在每个press方法中,您可以更新currentIndex,如下所示:

DrawerListTile(
...
...
press: () {
currentIndex.value = 0; // tile index
},
);

最新更新