Is there a way to control the leading element behavior of NavigationRail in Flutter?

0

Flutter recently launched their v1.17 (latest stable release) and in that they have included a new widget "Navigation Rail".

Though this widget is still in its early stages(and I'm expecting a bit more additional properties like padding for NavigationRailDestination) it gives a whole new perspective to orthodox navigation.

So while Implementing this widget I've encountered a problem to which I'm searching for a workaround maybe a solution(if anybody has one!).

And that problem is when we try to implement the toggle between leading elements and the navigationRailDestinations using setState(){...} , the toggling happens only once and not for the whole lifecycle of the app.

I'm struggling to implement it please help!.

Here's the code snippet:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  int _selectedIndex = 0, menuColor = 0xFfFCCFA8;
  final padding = 8.0;

  //bool leadingProfileFlag = false, leadingSettingsFlag = false, contentFlag = true;
  String profilePic, contentView = "dash";

  getView(String contentView,int selectedIndex,int menuColor) {
    switch (contentView) {
      case 'MenuRails.selectedIndex':
        return MenuRails(selectedIndex: selectedIndex,menuColor: menuColor,);
      case '' : return MenuRails(selectedIndex: selectedIndex,menuColor: menuColor,);
      case '2' : return MenuRails(selectedIndex: selectedIndex,menuColor: menuColor,);
      case 'settings': return Expanded(child: Container());
      case 'profile' : return Expanded(child: Container());
      default: return MenuRails(selectedIndex: selectedIndex,menuColor: menuColor,);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xff28292E),
      resizeToAvoidBottomPadding: false,
      body: Row(
        children: <Widget>[
          NavigationRail(
            leading: Column(
              children: <Widget>[
                SizedBox(
                  height: 38,
                ),
                InkWell(
                  splashColor: Color(0xffFCCFA8),
                  onTap: () {
                    setState(() {
                      contentView = 'profile';
                    });
                  },
                  child: Center(
                    child: CircleAvatar(
                      radius: 16,
                      backgroundImage: profilePic != null
                          ? NetworkImage(profilePic)
                          : AssetImage('assets/dummy_profile.png'),
                    ),
                  ),
                ),
                SizedBox(
                  height: 88,
                ),
                RotatedBox(
                  quarterTurns: -1,
                  child: GestureDetector(
                    onTap: (){
                      setState(() {
                        contentView = 'settings';
                      });
                    },
                    child: IconButton(
                      icon: Icon(Icons.tune),
                      color: Color(0xffFCCFA8),
                      onPressed: () {
                        setState(() {});
                      },
                    ),
                  ),
                )
              ],
            ),
            backgroundColor: Color(0xff2D3035),
            groupAlignment: 1.0,
            minWidth: MediaQuery.of(context).size.width * 0.07,
            elevation: 8.0,
            minExtendedWidth: MediaQuery.of(context).size.width * 0.4,
            selectedIndex: _selectedIndex,
            onDestinationSelected: (int index) {
              setState(() {
                _selectedIndex = index;
                contentView = _selectedIndex.toString();
              });
            },
            selectedLabelTextStyle: TextStyle(
              color: Color(0xffFCCFA8),
              fontSize: 13,
              letterSpacing: 0.8,
              decoration: TextDecoration.underline,
              decorationThickness: 2.0,
            ),
            unselectedLabelTextStyle: TextStyle(
              fontSize: 13,
              letterSpacing: 0.8,
            ),
            labelType: NavigationRailLabelType.all,
            destinations: [
              buildRotatedTextRailDestination("Dashboard", padding),
              buildRotatedTextRailDestination("Shop", padding),
              buildRotatedTextRailDestination("Service", padding),
            ],
            /*
            trailing: Column(
              children: <Widget>[
                SizedBox(height: 15,),
                Icon(
                  Icons.exit_to_app,//Logout icon
                  color: Colors.white70,
                ),
                SizedBox(height: 10,)
              ],
            ),
             */
          ),
          //VerticalDivider(thickness: 1, width: 1),
          // This is the main content.
          getView(contentView,_selectedIndex,menuColor),
        ],
      ),
    );
  }

  Widget menuRail() {

  }

  NavigationRailDestination buildRotatedTextRailDestination(
      String text, double padding) {
    return NavigationRailDestination(
      icon: SizedBox.shrink(),
      label: Padding(
        padding: EdgeInsets.symmetric(vertical: padding),
        child: RotatedBox(
          quarterTurns: -1,
          child: Text(text),
        ),
      ),
    );
  }
}
// ignore: must_be_immutable
class MenuRails extends StatefulWidget {
  int menuColor;
  final int selectedIndex;
  MenuRails({this.menuColor,this.selectedIndex});
  @override
  _MenuRailsState createState() => _MenuRailsState();
}

class _MenuRailsState extends State<MenuRails> {
  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: Container(
        color: Colors.black54,
        child: Column(
          children: <Widget>[
            SizedBox(height: MediaQuery.of(context).size.height * 0.07),
            Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: <Widget>[
                IconButton(
                  icon: Icon(
                    Icons.clear_all,
                    color: Color(widget.menuColor),
                  ),
                  onPressed: () {
                    setState(() {
                      if (widget.menuColor == 0xFfFCCFA8)
                        widget.menuColor = 0xffffffff;
                      else
                        widget.menuColor = 0xFfFCCFA8;
                    });
                  },
                ),
                SizedBox(
                  width: MediaQuery.of(context).size.width * 0.07,
                )
              ],
            ),
            SizedBox(height: MediaQuery.of(context).size.height * 0.02),
            Expanded(
              child: Padding(
                padding: EdgeInsets.fromLTRB(
                    MediaQuery.of(context).size.width * 0.08, 0, 0, 0),
                child: ClipRRect(
                  borderRadius: BorderRadius.only(topLeft: Radius.circular(55)),
                  child: Container(
                    color: Color(0xfffff9c4),
                    height: MediaQuery.of(context).size.height,
                    // Here we have to write code for content.
                    child: Center(
                      child: Text(
                        'selectedIndex: $widget.selectedIndex',
                      ),
                    ),
                  ),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

flutter
flutter-layout
asked on Stack Overflow May 31, 2020 by user12112359 • edited May 31, 2020 by user12112359

1 Answer

1

Try using Navigation Rails with PageView inside the Expanded widget


class NavRail extends StatefulWidget {
  @override
  _NavRailState createState() => _NavRailState();
}

class _NavRailState extends State<NavRail> {
  int selectedIndex = 0;

  PageController pageController = PageController();

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Row(
        children: <Widget>[
          NavigationRail(
            labelType: NavigationRailLabelType.all,
            selectedIconTheme: IconThemeData(color: Colors.green),
            unselectedIconTheme: IconThemeData(color: Colors.blueGrey),
            selectedLabelTextStyle: TextStyle(color: Colors.green),
            unselectedLabelTextStyle: TextStyle(color: Colors.blueGrey),
            selectedIndex: selectedIndex,
            onDestinationSelected: (index) {
              setState(() {
                selectedIndex = index;
                pageController.animateToPage(index,
                    duration: Duration(milliseconds: 200),
                    curve: Curves.easeIn);
              });
            },
            destinations: [
              NavigationRailDestination(
                icon: Icon(Icons.home),
                label: Text('Home'),
              ),
              NavigationRailDestination(
                icon: Icon(Icons.info),
                label: Text('About'),
              ),
              NavigationRailDestination(
                icon: Icon(Icons.message),
                label: Text('Feedback'),
              ),
            ],
          ),
          Expanded(
              child: PageView(
            controller: pageController,
            scrollDirection: Axis.horizontal,
            children: <Widget>[
              Container(
                color: Colors.blue,
              ),
              Container(
                color: Colors.green,
              ),
              Container(
                color: Colors.indigo,
              ),
            ],
          ))
        ],
      ),
    );
  }
}


answered on Stack Overflow Jun 27, 2020 by kennyboi29

User contributions licensed under CC BY-SA 3.0