Como fazer um menu lateral em um Flutter
O widget Drawer (material library import ‘package:flutter/material.dart’ ) recebe um parâmetro child, que é um widget que aparece na parte superior do menu, geralmente como um título ou cabeçalho. O parâmetro chield geralmente é um widget DrawerHeader, que fornece um espaço para exibir um título ou logotipo.
Código
Drawer Drawer({ Key? key, Color? backgroundColor, double? elevation, Color? shadowColor, Color? surfaceTintColor, ShapeBorder? shape, double? width, Widget? child, String? semanticLabel, })
O widget Drawer também usa widgets ListView ou Column of ListTile como seu conteúdo principal. Cada ListTile representa um item de menu e a propriedade onTap do ListTile pode ser usada para lidar com a interação do usuário quando o item de menu é selecionado.
Para criar um menu lateral em um aplicativo Flutter, você pode usar o widget Drawer da seguinte maneira:
- Adicione o widget Scaffold ao método de construção de sua tela, que fornecerá a estrutura básica para sua tela.
- Dentro do Scaffold, adicione um widget AppBar à propriedade appBar. Isso criará a barra de aplicativos na parte superior da tela.
- Dentro do Scaffold, adicione um widget Drawer à propriedade da gaveta. Isso criará o menu lateral.
- Dentro do Drawer, adicione um widget Column com seus itens de menu como widgets ListTile.
- Na propriedade onTap de cada ListTile, adicione o código para navegar até a tela correspondente ou execute a ação apropriada.
- UserAccountsDrawerHeader – mostra as informações do usuário no cabeçalho do menu lateral.
Conteudo
Barra superior do menu (DrawerHeader)
Code(DrawerHeader)
Container( child: UserAccountsDrawerHeader( decoration: BoxDecoration( color: WidgetColors.mainHeaderColor, ), accountName: InkWell( onTap: () {}, child: Text.rich( TextSpan( children: [ TextSpan( text: myAccountName ?? 'NA', style: TextStyle( color: Colors.white, fontSize: 24.0, ), ), TextSpan(text: ' '), ], ), ), ), accountEmail: Text(myGroupType), currentAccountPicture: InkWell( onTap: () { Navigator.of(context).push(MaterialPageRoute( builder: (_) => EditProfileImage( nameInfo: myAccountName.toString(), ))); }, child: Stack( children: <Widget>[ Container( width: 250, height: 250, child: CircleAvatar( backgroundColor: AppTheme.mainColor, radius: 43, child: ClipOval( child: FadeInImage( fadeInDuration: const Duration(milliseconds: 500), placeholder: const AssetImage('assets/images/userL.png'), image: vThumbImage == null ? NetworkImage( "https://img.icons8.com/fluency/48/null/no-image.png") : NetworkImage(vThumbImage!), imageErrorBuilder: (context, error, stackTrace) { return Container( child: Image.asset("assets/images/userL.png")); }, fit: BoxFit.cover, height: 70, width: 70, ), ), ), ), Positioned( bottom: 1, right: 1, child: Container( height: 35, width: 35, child: InkWell( child: const Icon( Icons.add_a_photo, size: 15.0, color: Color(0xFF404040), ), ), decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20))), )) ], ), ), )),
Código final
Drawer( child: ListView( padding: EdgeInsets.zero, children: <Widget>[ //------------user image section and other deatils // Container( child: UserAccountsDrawerHeader( decoration: BoxDecoration( color: WidgetColors.mainHeaderColor, ), accountName: InkWell( onTap: () {}, child: Text.rich( TextSpan( children: [ TextSpan( text: myAccountName ?? 'NA', style: TextStyle( color: Colors.white, fontSize: 24.0, ), ), TextSpan(text: ' '), ], ), ), ), accountEmail: Text('yourEmail@gmail.com'), currentAccountPicture: InkWell( onTap: () { //-your action }, child: Stack( children: <Widget>[ Container( width: 250, height: 250, child: CircleAvatar( backgroundColor: AppTheme.mainColor, radius: 43, child: ClipOval( child: FadeInImage( fadeInDuration: const Duration(milliseconds: 500), placeholder: const AssetImage('assets/images/userL.png'), image: vThumbImage == null ? NetworkImage( "https:xxxx/no-image.png") : NetworkImage(vThumbImage!), imageErrorBuilder: (context, error, stackTrace) { return Container( child: Image.asset("assets/images/userL.png")); }, fit: BoxFit.cover, height: 70, width: 70, ), ), ), ), Positioned( bottom: 1, right: 1, child: Container( height: 35, width: 35, child: InkWell( // onTap: _onAlertPress, child: const Icon( Icons.add_a_photo, size: 15.0, color: Color(0xFF404040), ), ), decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20))), )) ], ), ), )), //--------menu list ------------------// ListTile( leading: Icon(Icons.home), title: Text( 'side_MenuHome'.tr, style: TextStyle( fontSize: 15.0, color: Colors.black, letterSpacing: 0, ), ), onTap: () => selectedItem(context, 0), ), ListTile( leading: Icon(Icons.history_rounded), title: Text( 'side_MenuOrderHistory'.tr, style: TextStyle( fontSize: 15.0, color: Colors.black, letterSpacing: 0, ), ), onTap: () => selectedItem(context, 1), ), ListTile( leading: Icon(Icons.payment), title: Text( 'side_MenuPaymentHistory'.tr, style: TextStyle( fontSize: 15.0, color: Colors.black, letterSpacing: 0, ), ), onTap: () => selectedItem(context, 2), ), ListTile( leading: Icon( Icons.settings, color: Colors.black54, ), title: Text( 'side_MenuSettings'.tr, style: TextStyle( fontSize: 15.0, color: Colors.black, letterSpacing: 0, ), ), onTap: () => selectedItem(context, 3), ), ListTile( leading: Image.asset( "assets/images/location.png", width: 25, height: 25, fit: BoxFit.fill, color: Colors.black54, ), title: Text( 'side_MenuChooseLocation'.tr, style: TextStyle( fontSize: 15.0, color: Colors.black, letterSpacing: 0, ), ), onTap: () => selectedItem(context, 4), ), ListTile( leading: Image.asset( "assets/images/complain.png", width: 25, height: 25, fit: BoxFit.fill, color: Colors.black54, ), title: Text( "Support", style: TextStyle( fontSize: 15.0, color: Colors.black, letterSpacing: 0, ), ), onTap: () => selectedItem(context, 5), ), ListTile( leading: Image.asset( "assets/images/feedback.png", width: 25, height: 25, fit: BoxFit.fill, color: Colors.black54, ), title: Text( "Feedback", style: TextStyle( fontSize: 15.0, color: Colors.black, letterSpacing: 0, ), ), onTap: () => selectedItem(context, 6), ), ListTile( leading: Icon(Icons.update), title: Text( 'side_MenuUpdate'.tr, style: TextStyle( fontSize: 15.0, color: Colors.black, letterSpacing: 0, ), ), onTap: () { Fluttertoast.showToast( msg: "Currently no updates available!", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, timeInSecForIosWeb: 1, backgroundColor: AppTheme.mainTextColor, textColor: Colors.white, fontSize: 16.0); print("update Click"); }, ), Divider( color: Colors.black38, ), ListTile( leading: Image.asset( "assets/images/logout.png", width: 25, height: 25, fit: BoxFit.fill, color: Colors.black54, ), title: Text('side_MenuLogout'.tr), onTap: () async { showDialog( context: context, builder: (context) { return AlertDialog( title: Text('Logout'), content: Text('side_MenuLogoutMessage'.tr), actions: <Widget>[ TextButton( onPressed: () => Navigator.of(context).pop(), child: Text( 'side_MenuLogoutNo'.tr, style: TextStyle(color: Colors.red), )), TextButton( onPressed: () async { SharedPreferences prefs = await SharedPreferences.getInstance(); var groupId = prefs.getString('groupId') ?? ''; var userId = prefs.getString('userId') ?? ''; var password = prefs.getString('password') ?? ''; await prefs.remove("accountId"); await prefs.remove("AccountName"); Navigator.pushAndRemoveUntil( context, MaterialPageRoute( builder: (BuildContext context) => LoginNewPro(groupId, userId, password)), ModalRoute.withName('/')); }, child: Text( 'side_MenuLogoutYes'.tr, style: TextStyle(color: Colors.red), ), ), ], ); }); }, ), //----------------------end code-------------------// ], ), ); }
Quando o usuário toca em um item de menu, navegamos para a tela correspondente usando o widget Navigator. Usamos o método pushReplacement para substituir a tela atual pela nova tela e exibir a tela anterior.
void selectedItem(BuildContext context, int index) { // Navigator.of(context).pop(); print(index); switch (index) { case 0: Navigator.pushReplacementNamed(context, "/home"); break; case 1: Navigator.pushReplacementNamed(context, "/profile"); break; case 2: Navigator.pushReplacementNamed( context, "/marketOrderHistory"); break; case 3: Navigator.pushReplacementNamed(context, "/paymenthistory"); break; case 4: Navigator.pushReplacementNamed(context, "/paymentdeatils"); break; case 5: Navigator.pushReplacementNamed(context, "/settings"); break; case 6: Navigator.pushReplacementNamed(context, "/chooseLocation"); break; case 7: Navigator.pushReplacementNamed(context, "/feedback"); break; case 8: Navigator.pushReplacementNamed(context, "/contactus"); break; } }
Conclusão
Assim, aprendemos como fazer um menu lateral no Flutter, foi feito menu lateral de forma simples. Este exemplo acima ajuda seu próximo projeto a vincular e criar rapidamente e aproveitar se houver algum problema, comente e sinta-se à vontade para entrar em contato conosco a qualquer momento.