j.itD
j.itD

Reputation: 61

How to use Flutter GetX Sidebar

How can I implement the design in the image (sidebar and navigation menu) in Flutter using GetX? similarly to Tabs on the web. Flutter Sidebar with GetX

Upvotes: 5

Views: 2921

Answers (3)

Cena Ashoori
Cena Ashoori

Reputation: 13

For the main content put all the different view into a list and put it into PageView. And create a custom navigator and put these two widget into a Row:

Controller:

    class SettingsController extends GetxController {
      final PageController pageController =
          PageController(initialPage: 1, keepPage: true);
    }

Sidebar:

    class MySideNavigation extends StatefulWidget {
      MySideNavigation({Key? key}) : super(key: key);
    
      @override
      State<MySideNavigation> createState() => _MySideNavigationState();
    }
    
    class _MySideNavigationState extends State<MySideNavigation> {
      @override
      Widget build(BuildContext context) {
        final SettingsController c = Get.find();
        return NavigationRail(
          selectedIndex: c.selectedViewIndex.value,
          onDestinationSelected: (value) async {
            setState(() {
              c.selectedViewIndex(value);
              c.pageController.jumpToPage(
                value,
                // duration: Duration(milliseconds: 500), curve: Curves.decelerate
              );
            });
          },
          labelType: NavigationRailLabelType.selected,
          destinations: const <NavigationRailDestination>[
            NavigationRailDestination(
              icon: Icon(Icons.map_outlined),
              selectedIcon: Icon(Icons.map_rounded),
              label: Text(
                'نقشه ها',
                style: TextStyle(fontSize: 14, fontFamily: 'Vazir'),
              ),
            ),
            NavigationRailDestination(
              icon: Icon(Icons.map_outlined),
              selectedIcon: Icon(Icons.map_rounded),
              label: Text(
                'نقشه ها',
                style: TextStyle(fontSize: 14, fontFamily: 'Vazir'),
              ),
            ),
            NavigationRailDestination(
              icon: Icon(Icons.person_outline),
              selectedIcon: Icon(Icons.person),
              label: Text(
                'پروفایل',
                style: TextStyle(fontSize: 14, fontFamily: 'Vazir'),
              ),
            ),
          ],
        );
      }
    }

GotFatherView:

    class GodFatherView extends StatelessWidget {
          GodFatherView({Key? key}) : super(key: key);
          final PageStorageBucket bucket = PageStorageBucket();
          final SettingsController c = Get.find();
          List<Widget> pages = [
            const KeepAlivePage(Page1()),
            KeepAlivePage(Page2()),
            const KeepAlivePage(Page3()),
          ];
          @override
          Widget build(BuildContext context) {
            return Scaffold(
                body: Row(
              children: [
                MySideNavigation(),
                Expanded(
                  child: PageView(
                    controller: c.pageController,
                    children: pages,
                  ),
                )
              ],
            ));
          }
        }

tap on below link to open screenshot: I don't have enough reputation to post image :))))))

Screeshot

Give a special attention to the sidebar navigator in MySideNavigation class:

    NavigationRail(
          selectedIndex: c.selectedViewIndex.value,
          onDestinationSelected: (value) async {
            setState(() {
              c.pageController.jumpToPage(value);
            });
          },

When user tap on each NavigationRailDestination ,onDestinationSelected function will be called with an index. The index are representing the index of the destination view. Example: When user on [Page1() -> index:0] tab on the second NavigationRailDestination the index inside of function is 1, so you can use the PageController to navigate into [Page2() -> index:1].

Attention, Attention, More Attention:

If you don't like to lose the state(I mean when u navigate to another view and back to previous view don't rebuild it again). Sometimes we need to keep the state of widget, we change something, write something into a text field and etc. If you don't wrap it with this widget all the data will be loosed(or you can save it through another way).

Wrap your widget with this Widget see the GodFather View I wrap all pages with KeepAlivePage, In this widget I extend State of the widget with 'AutomaticKeepAliveClientMixin' and override its value bool get wantKeepAlive => true; .

import 'package:flutter/material.dart';

class KeepAlivePage extends StatefulWidget {
  const KeepAlivePage(this.child, {Key? key}) : super(key: key);
  final child;

  @override
  State<KeepAlivePage> createState() => _KeepAlivePageState();
}

class _KeepAlivePageState extends State<KeepAlivePage>
    with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return widget.child;
  }

  @override
  // TODO: implement wantKeepAlive
  bool get wantKeepAlive => true;
}

Upvotes: 1

six god
six god

Reputation: 51

it's easy,just let your right conent use GetMaterialApp and the route change is render right concent, then left sidler is a component warp your menuslider, last control you left slider menuchange index. show my code

 Widget build(BuildContext context) {
    return ScreenUtilInit(
        designSize: const Size(dessignWidth, dessignHeight),
        builder: () => BarcodeKeyboardListener(
            onBarcodeScanned: (String codeValue) {},
            child: Material(
              child: MaterialApp(
                  localizationsDelegates: const [
                    GlobalMaterialLocalizations.delegate,
                    GlobalWidgetsLocalizations.delegate,
                  ],
                  supportedLocales: const [
                    Locale('zh', 'CH'),
                    Locale('en', 'US'),
                  ],
                  home: Row(
                    children: [
                      Material(
                        child: SliderMenu(),
                      ),
                      Expanded(
                          child: GetMaterialApp(
                              debugShowCheckedModeBanner: false,
                              enableLog: true,
                              navigatorKey: Get.key,
                              routingCallback: RouteChangeMiddleWare.observer,
                              logWriterCallback: Logger.write,
                              initialRoute: AppPages.INITIAL,
                              getPages: AppPages.routes,
                              unknownRoute: AppPages.unknownRoute,
                              builder: EasyLoading.init(),
                              onInit: () =>
                                  {logger.v('Global.CONFIG', AppConfig)}))
                    ],
                  )),
            )));
  }```
hope to help you;


Upvotes: 0

Williams Bobadilla
Williams Bobadilla

Reputation: 149

This is a example, maybe it can help you:

import 'package:flutter/material.dart';
import '../../routes/app_pages.dart';
import 'package:get/get.dart';

class SideBar extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Drawer(
      child: Column(
        children: <Widget>[
          DrawerHeader(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                Center(
                  child: Icon(
                    Icons.person,
                    color: Colors.white,
                    size: 50.0,
                  ),
                ),
                Center(
                  child: Text(
                    "Vakup",
                    textAlign: TextAlign.center,
                    style: TextStyle(color: Colors.white, fontSize: 25),
                  ),
                ),
              ],
            ),
            decoration: BoxDecoration(
              color: Colors.blueAccent,
            ),
          ),
          ListTile(
            leading: Icon(Icons.read_more),
            title: Text('Leer datos'),
            onTap: () {
              if (Get.currentRoute == Routes.HOME) {
                Get.back();
              } else {
                Get.toNamed(Routes.HOME);
              }
            },
          ),
          ListTile(
            leading: Icon(Icons.pets),
            title: Text('Registrar animal'),
            onTap: () {
              if (Get.currentRoute == Routes.NEWANIMAL) {
                Get.back();
              } else {
                Get.toNamed(Routes.NEWANIMAL);
              }
            },
          ),
          ListTile(
            leading: Icon(Icons.list_alt),
            title: Text('Lista movimientos'),
            onTap: () {
              if (Get.currentRoute == Routes.MOVEMENTS) {
                Get.back();
              } else {
                //Get.to
                Get.toNamed(Routes.MOVEMENTS);
              }
            },
          ),
          ListTile(
            leading: Icon(Icons.list),
            title: Text('Lista animales'),
            onTap: () {
              if (Get.currentRoute == Routes.LISTOFANIMALS) {
                Get.back();
              } else {
                Get.toNamed(Routes.LISTOFANIMALS);
              }
            },
          ),
          ListTile(
            leading: Icon(Icons.edit),
            title: Text('Grabar datos'),
            onTap: () {
              if (Get.currentRoute == Routes.GRABADO) {
                Get.back();
              } else {
                Get.toNamed(Routes.GRABADO);
              }
            },
          ),
          ListTile(
            leading: Icon(Icons.bluetooth),
            title: Text('Conexion BT'),
            onTap: () {
              if (Get.currentRoute == Routes.CONEXIONBT) {
                Get.back();
              } else {
                Get.toNamed(Routes.CONEXIONBT);
              }
            },
          ),
          ListTile(
            leading: Icon(Icons.picture_as_pdf),
            title: Text('Exportar Datos'),
            onTap: () {
              if (Get.currentRoute == Routes.EXPORT) {
                Get.back();
              } else {
                Get.toNamed(Routes.EXPORT);
              }
            },
          ),
          ListTile(
            leading: Icon(Icons.recent_actors_rounded),
            title: Text('Acerca de'),
            onTap: () {
              if (Get.currentRoute == Routes.ACERCA) {
                Get.back();
              } else {
                Get.toNamed(Routes.ACERCA);
              }
            },
          ),
        ],
      ),
    );
  }
}

And the home part is:

import 'package:vakuprfid/app/modules/widgets/side_bar.dart';//import widget

class HomeView extends GetView<HomeController> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        drawer: SideBar(),
        body: ...
      );
   }
}

This is the result:

Upvotes: 1

Related Questions