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',
),
),
),
),
),
)
],
),
),
);
}
}
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,
),
],
))
],
),
);
}
}