Une barre de navigation inférieure persistante/statique pour Flutter.
REMARQUE : Ceux qui migrent de avant 2.0.0 version doit vérifier le dernier fichier Lisezmoi et les instructions car de nombreux changements de rupture ont été introduits dans la mise à jour 2.0.0
modes
Style15 | Style16 |
---|---|
![]() |
![]() |
Style1 | Style9 |
---|---|
![]() |
![]() |
Style7 | Style10 |
---|---|
![]() |
![]() |
Style12 | Style13 |
---|---|
![]() |
![]() |
Style3 | Style6 |
---|---|
![]() |
![]() |
Neumorphique | Neumorphique sans sous-titre |
---|---|
![]() |
![]() |
Remarque : Ceux-ci n’incluent pas toutes les variations de style
Caractéristiques
- Hautement personnalisable
persistent
barre de navigation inférieure. - Possibilité de pousser de nouveaux écrans avec ou sans barre de navigation inférieure.
- 20 styles pour la barre de navigation inférieure.
- Comprend des fonctions pour pousser l’écran avec ou sans la barre de navigation inférieure, c’est-à-dire pushNewScreen() et pushNewScreenWithRouteSettings().
- Basé sur la barre de navigation inférieure de Flutter Cupertino (iOS).
- Peut être
translucent
pour un onglet particulier. - Style personnalisé pour la barre de navigation. Cliquez sur ici pour plus d’informations.
- Gère le bouton arrière Android matériel/logiciel.
Commencer
Dans votre projet flutter, ajoutez la dépendance :
dependencies:
persistent_bottom_nav_bar: any
Importez le package :
import 'package:persistent_bottom_nav_bar/persistent_tab_view.dart';
La barre de navigation inférieure persistante utilise PersistentTabController
comme son contrôleur. Voici comment le déclarer :
PersistentTabController _controller;
_controller = PersistentTabController(initialIndex: );
Le widget principal à déclarer ensuite est PersistentTabView
. REMARQUE : ce widget inclut SCAFFOLD (basé sur CupertinoTabScaffold
), donc pas besoin de le déclarer. Voici un exemple à des fins de démonstration :
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return PersistentTabView(
context,
controller: _controller,
screens: _buildScreens(),
items: _navBarsItems(),
confineInSafeArea: true,
backgroundColor: Colors.white, // Default is Colors.white.
handleAndroidBackButtonPress: true, // Default is true.
resizeToAvoidBottomInset: true, // This needs to be true if you want to move up the screen when keyboard appears. Default is true.
stateManagement: true, // Default is true.
hideNavigationBarWhenKeyboardShows: true, // Recommended to set 'resizeToAvoidBottomInset' as true while using this argument. Default is true.
decoration: NavBarDecoration(
borderRadius: BorderRadius.circular(10.0),
colorBehindNavBar: Colors.white,
),
popAllScreensOnTapOfSelectedTab: true,
popActionScreens: PopActionScreensType.all,
itemAnimationProperties: ItemAnimationProperties( // Navigation Bar's items animation properties.
duration: Duration(milliseconds: 200),
curve: Curves.ease,
),
screenTransitionAnimation: ScreenTransitionAnimation( // Screen transition animation on change of selected tab.
animateTabTransition: true,
curve: Curves.ease,
duration: Duration(milliseconds: 200),
),
navBarStyle: NavBarStyle.style1, // Choose the nav bar style with this property.
);
}
}
List<Widget> _buildScreens() {
return [
MainScreen(),
SettingsScreen()
];
}
List<PersistentBottomNavBarItem> _navBarsItems() {
return [
PersistentBottomNavBarItem(
icon: Icon(CupertinoIcons.home),
title: ("Home"),
activeColorPrimary: CupertinoColors.activeBlue,
inactiveColorPrimary: CupertinoColors.systemGrey,
),
PersistentBottomNavBarItem(
icon: Icon(CupertinoIcons.settings),
title: ("Settings"),
activeColorPrimary: CupertinoColors.activeBlue,
inactiveColorPrimary: CupertinoColors.systemGrey,
),
];
}
Fonctions du navigateur
Remarque : Vous pouvez toujours utiliser les fonctions Navigator habituelles telles que « pushNamed », mais assurez-vous de vérifier l’argument routeAndNavigatorSettings
ton PersistentBottomNavBarItem
pour les paramètres d’itinéraire et certaines autres propriétés liées au navigateur
Pour pousser un nouvel écran, utilisez les fonctions suivantes pour contrôler le visibility
de la barre de navigation inférieure sur un écran particulier. Vous pouvez utiliser votre propre logique pour implémenter platform-specific
comportement. Une des solutions pourrait être d’utiliser la propriété withNavBar
et basculez-le en fonction de la plate-forme.
Dans platform-specific
comportement, tout en poussant un nouvel écran, sur Android
il poussera l’écran SANS la barre de navigation inférieure mais sur iOS
il persistera dans la barre de navigation inférieure. Il s’agit du comportement par défaut spécifié par chaque plate-forme.
PersistentNavBarNavigator.pushNewScreen(
context,
screen: MainScreen(),
withNavBar: true, // OPTIONAL VALUE. True by default.
pageTransitionAnimation: PageTransitionAnimation.cupertino,
);
PersistentNavBarNavigator.pushNewScreenWithRouteSettings(
context,
settings: RouteSettings(name: MainScreen.routeName),
screen: MainScreen(),
withNavBar: true,
pageTransitionAnimation: PageTransitionAnimation.cupertino,
);
Si vous poussez un nouveau modal
l’écran, utilisez la fonction suivante :
PersistentNavBarNavigator.pushDynamicScreen(
context,
screen: HomeModalScreen(),
withNavBar: true,
);
Quelques conseils utiles
-
Accédez à n’importe quel écran du graphique de navigation pour un onglet donné :
Navigator.of(context).popUntil((route) { return route.settings.name == "ScreenToPopBackTo"; });
-
Revenir au premier écran du graphique de navigation pour un onglet donné :
Navigator.of(context).popUntil(ModalRoute.withName("/"));
Navigator.of(context).pushAndRemoveUntil( CupertinoPageRoute( builder: (BuildContext context) { return FirstScreen(); }, ), (_) => false, );
-
Pour pousser la feuille inférieure en haut de la barre de navigation, utilisez showModalBottomScreen et définissez sa propriété
useRootNavigator
à vrai. Voir exemple de projet pour une illustration.
Style de barre de navigation personnalisé
Si vous souhaitez avoir votre propre style pour la barre de navigation, procédez comme suit :
-
Déclarez votre widget personnalisé. Veuillez garder à l’esprit que vous devrez gérer la fonction
onSelectedItem
et l’entierselectedIndex
vous-même pour conserver toutes les fonctionnalités. Veuillez également noter que vous pouvez définir votre propre modèle pour l’élément de la barre de navigation au lieu de celui fourniPersistentBottomNavBarItem
. Voir cet exemple ci-dessous pour une meilleure compréhension :class CustomNavBarWidget extends StatelessWidget { final int selectedIndex; final List<PersistentBottomNavBarItem> items; // NOTE: You CAN declare your own model here instead of `PersistentBottomNavBarItem`. final ValueChanged<int> onItemSelected; CustomNavBarWidget( {Key key, this.selectedIndex, @required this.items, this.onItemSelected,}); Widget _buildItem( PersistentBottomNavBarItem item, bool isSelected) { return Container( alignment: Alignment.center, height: 60.0, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: <Widget>[ Flexible( child: IconTheme( data: IconThemeData( size: 26.0, color: isSelected ? (item.activeColorSecondary == null ? item.activeColorPrimary : item.activeColorSecondary) : item.inactiveColorPrimary == null ? item.activeColorPrimary : item.inactiveColorPrimary), child: item.icon, ), ), Padding( padding: const EdgeInsets.only(top: 5.0), child: Material( type: MaterialType.transparency, child: FittedBox( child: Text( item.title, style: TextStyle( color: isSelected ? (item.activeColorSecondary == null ? item.activeColorPrimary : item.activeColorSecondary) : item.inactiveColorPrimary, fontWeight: FontWeight.w400, fontSize: 12.0), )), ), ) ], ), ); } @override Widget build(BuildContext context) { return Container( color: Colors.white, child: Container( width: double.infinity, height: 60.0, child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: items.map((item) { int index = items.indexOf(item); return Flexible( child: GestureDetector( onTap: () { this.onItemSelected(index); }, child: _buildItem( item, selectedIndex == index), ), ); }).toList(), ), ), ); } }
-
En général
PersistentTabView
widget, définissez lenavBarStyle
propriété commeNavBarStyle.custom
et transmettez le widget personnalisé que vous venez de créer dans lecustomWidget
propriété comme celle-ci :class MyApp extends StatelessWidget { const MyApp({Key key}) : super(key: key); @override Widget build(BuildContext context) { return PersistentTabView.custom( context, controller: _controller, itemCount: items.length, // This is required in case of custom style! Pass the number of items for the nav bar. screens: _buildScreens(), confineInSafeArea: true, handleAndroidBackButtonPress: true, onItemSelected: (int) { setState(() {}); // This is required to update the nav bar if Android back button is pressed }, customWidget: CustomNavBarWidget( // Your custom widget goes here items: _navBarsItems(), selectedIndex: _controller.index, onItemSelected: (index) { setState(() { _controller.index = index; // NOTE: THIS IS CRITICAL!! Don't miss it! }); }, ), ); } }
NOTE: In the 'onSelected' function of the customWidget, don't forgot to change the index of the controller
-
Fait! Comme nous pouvons le voir, certaines des autres propriétés comme
iconSize
,items
ne sont pas nécessaires ici, vous pouvez donc ignorer ces propriétés. Pour contrôler la rembourrage inférieur de l’écran, utilisezbottomScreenPadding
. Si tu donnes tropbottomScreenPadding
mais moins de hauteur dans le widget personnalisé ou vice versa, des problèmes de mise en page peuvent apparaître.
Pour une meilleure compréhension, reportez-vous au exemple de projet dans le dépôt git officiel.
GitHub
Voir Github