LCOV - code coverage report
Current view: top level - src/widgets - drawer_navigation_builder.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 53 0.0 %
Date: 2023-03-02 15:31:08 Functions: 0 0 -

          Line data    Source code
       1             : import 'package:flutter/material.dart';
       2             : 
       3             : import '../navigation_controller.dart';
       4             : import 'index.dart';
       5             : 
       6             : /// A [NavigatorBuilder] that allows to switch between destinations using
       7             : /// [Drawer].
       8             : ///
       9             : /// It builds a wrapper widget, which is a [Scaffold] with a [Scaffold.body] set
      10             : /// to the current destination's content, and [Scaffold.drawer] specified.
      11             : ///
      12             : /// The [drawerItems] must correspond to the navigator's destinations.
      13             : ///
      14             : /// The drawer can be customized using [parameters], which includes
      15             : /// all parameters supported by the [Drawer] widget.
      16             : ///
      17             : /// See also:
      18             : /// - [NavigatorBuilder]
      19             : /// - [DrawerParameters]
      20             : /// - [NavigationController]
      21             : /// - [Drawer]
      22             : ///
      23             : class DrawerNavigationBuilder extends NavigatorBuilder {
      24             :   /// Creates a [DrawerNavigationBuilder] instance.
      25             :   ///
      26           0 :   const DrawerNavigationBuilder({
      27             :     required this.drawerItems,
      28             :     this.header,
      29             :     this.parameters,
      30           0 :   }) : super();
      31             : 
      32             :   /// A list of [DrawerItems], that corresponds to the navigator's
      33             :   /// destination list.
      34             :   ///
      35             :   /// The list must contain the same number of drawer items,
      36             :   /// following with the same order as a destination list specified for the navigator.
      37             :   ///
      38             :   final List<DrawerItem> drawerItems;
      39             : 
      40             :   /// Optional header, that is shown at the top of drawer.
      41             :   ///
      42             :   final Widget? header;
      43             : 
      44             :   /// A set of [Drawer`] parameters.
      45             :   ///
      46             :   /// Contains all supported parameters to customize [Drawer] widget.
      47             :   /// Doesn't include 'child', which is managed by [DrawerNavigationBuilder].
      48             :   ///
      49             :   final DrawerParameters? parameters;
      50             : 
      51           0 :   @override
      52             :   Widget build(BuildContext context, NavigationController navigator) {
      53           0 :     final currentDestination = navigator.currentDestination;
      54           0 :     final content = currentDestination.build(context);
      55           0 :     return _DrawerWrapper(
      56             :       content: content,
      57           0 :       items: drawerItems,
      58           0 :       header: header,
      59           0 :       parameters: parameters,
      60           0 :       onSelectItem: (index) => navigator.goTo(navigator.destinations[index]),
      61           0 :       selectedIndex: navigator.destinations.indexOf(currentDestination),
      62             :     );
      63             :   }
      64             : }
      65             : 
      66             : class _DrawerWrapper extends StatefulWidget {
      67           0 :   const _DrawerWrapper({
      68             :     Key? key,
      69             :     required this.content,
      70             :     required this.items,
      71             :     required this.onSelectItem,
      72             :     required this.selectedIndex,
      73             :     this.header,
      74             :     this.parameters,
      75           0 :   }) : super(key: key);
      76             : 
      77             :   final Widget content;
      78             : 
      79             :   final List<DrawerItem> items;
      80             : 
      81             :   final void Function(int) onSelectItem;
      82             : 
      83             :   final int selectedIndex;
      84             : 
      85             :   final Widget? header;
      86             : 
      87             :   final DrawerParameters? parameters;
      88             : 
      89           0 :   @override
      90           0 :   _DrawerWrapperState createState() => _DrawerWrapperState();
      91             : }
      92             : 
      93             : class _DrawerWrapperState extends State<_DrawerWrapper> {
      94             :   late final OverlayEntry _mainOverlay;
      95             : 
      96           0 :   @override
      97             :   void initState() {
      98           0 :     super.initState();
      99           0 :     _mainOverlay = OverlayEntry(
     100           0 :       builder: (context) => Row(
     101           0 :         children: [
     102           0 :           Drawer(
     103           0 :               backgroundColor: widget.parameters?.backgroundColor,
     104           0 :               elevation: widget.parameters?.elevation,
     105           0 :               shape: widget.parameters?.shape,
     106           0 :               width: widget.parameters?.width,
     107           0 :               semanticLabel: widget.parameters?.semanticLabel,
     108           0 :               child: ListView(
     109             :                 padding: EdgeInsets.zero,
     110           0 :                 children: [
     111           0 :                   if (widget.header != null) widget.header!,
     112           0 :                   ...widget.items
     113           0 :                       .map((item) => ListTile(
     114           0 :                             leading: item.leading,
     115           0 :                             title: Text(item.title ?? ''),
     116           0 :                             selected: widget.selectedIndex ==
     117           0 :                                 widget.items.indexOf(item),
     118           0 :                             selectedColor: widget.parameters?.selectedColor,
     119             :                             selectedTileColor:
     120           0 :                                 widget.parameters?.selectedTileColor,
     121           0 :                             onTap: () =>
     122           0 :                                 widget.onSelectItem(widget.items.indexOf(item)),
     123             :                           ))
     124           0 :                       .toList(),
     125             :                 ],
     126             :               )),
     127           0 :           Expanded(
     128           0 :             child: Scaffold(
     129           0 :               body: widget.content,
     130             :             ),
     131             :           ),
     132             :         ],
     133             :       ),
     134             :     );
     135             :   }
     136             : 
     137           0 :   @override
     138             :   void didUpdateWidget(_DrawerWrapper oldWidget) {
     139           0 :     super.didUpdateWidget(oldWidget);
     140           0 :     if (oldWidget.selectedIndex != widget.selectedIndex) {
     141           0 :       _mainOverlay.markNeedsBuild();
     142             :     }
     143             :   }
     144             : 
     145           0 :   @override
     146             :   Widget build(BuildContext context) {
     147           0 :     return Overlay(
     148           0 :       initialEntries: [
     149           0 :         _mainOverlay,
     150             :       ],
     151             :     );
     152             :   }
     153             : }
     154             : 
     155             : /// A model of drawer item.
     156             : ///
     157             : /// The data provided in the model is used to create a [ListTile] widget, which
     158             : /// represents the drawer list item.
     159             : ///
     160             : class DrawerItem {
     161             :   /// Creates an instance of [DrawerItem].
     162             :   ///
     163           0 :   const DrawerItem({
     164             :     this.leading,
     165             :     this.title,
     166             :   });
     167             : 
     168             :   /// A leading widget in the drawer item.
     169             :   ///
     170             :   /// Usually it is an icon, but could be any widget.
     171             :   ///
     172             :   final Widget? leading;
     173             : 
     174             :   /// An item's title.
     175             :   ///
     176             :   final String? title;
     177             : }
     178             : 
     179             : /// Contains parameters to customize the [Drawer].
     180             : ///
     181             : /// It includes all the same arguments as the [Drawer()], excepting
     182             : /// the 'child', which is managed by the [DrawerNavigationBuilder].
     183             : ///
     184             : /// In addition it includes some parameters of [ListTile()] that are used to style
     185             : /// selected drawer item.
     186             : ///
     187             : /// See also:
     188             : /// - [DrawerNavigationBuilder]
     189             : /// - [Drawer]
     190             : /// - [ListTile]
     191             : ///
     192             : class DrawerParameters {
     193             :   /// Create a [DrawerParameters] instance.
     194             :   ///
     195           0 :   const DrawerParameters({
     196             :     this.backgroundColor,
     197             :     this.elevation,
     198             :     this.shape,
     199             :     this.width,
     200             :     this.semanticLabel,
     201             :     this.selectedColor,
     202             :     this.selectedTileColor,
     203             :   });
     204             : 
     205             :   /// [Drawer.backgroundColor]
     206             :   ///
     207             :   final Color? backgroundColor;
     208             : 
     209             :   /// [Drawer.elevation]
     210             :   ///
     211             :   final double? elevation;
     212             : 
     213             :   /// [Drawer.shape]
     214             :   ///
     215             :   final ShapeBorder? shape;
     216             : 
     217             :   /// [Drawer.width]
     218             :   ///
     219             :   final double? width;
     220             : 
     221             :   /// [Drawer.semanticLabel]
     222             :   ///
     223             :   final String? semanticLabel;
     224             : 
     225             :   /// [ListTile.selectedColor]
     226             :   ///
     227             :   final Color? selectedColor;
     228             : 
     229             :   /// [ListTile.selectedTileColor]
     230             :   ///
     231             :   final Color? selectedTileColor;
     232             : }

Generated by: LCOV version