Still learning Flutter and I'm wondering if it is possible to have a "fly-out" set of buttons in a NavigationRail?
The code base I'm starting to use is from the Flutter team here about the Flow class: https://api.flutter.dev/flutter/widgets/Flow-class.html
What I'm trying to do is add this to a NavigationRail. Below is the code I have for the Navigation rail and what I have so far for the Flow class with a single icon. The Error is at the bottom.
NavigationRail code:
body: Column(
children: <Widget>[
Expanded(
child: Row(
children: [
Visibility(
visible: !showBottomNav,
child: Flexible(
flex: 1,
child: NavigationRail(
backgroundColor: kQptColorLightGrey200,
elevation: 4,
selectedIconTheme: const IconThemeData(
color: kQptColorPrimaryDarkTeal,
),
selectedLabelTextStyle: const TextStyle(color: kQptColorPrimaryDarkTeal, fontSize: 14),
unselectedIconTheme: const IconThemeData(
color: kQptColorPrimaryDarkTeal,
),
unselectedLabelTextStyle: const TextStyle(color: kQptColorPrimaryDarkTeal, fontSize: 14),
labelType: NavigationRailLabelType.all,
destinations: [
NavigationRailDestination(
icon: Icon(
Icons.calendar_month,
size: 30,
),
label: FittedBox(
child: Text("Scheduler"),
),
),
NavigationRailDestination(
icon: Icon(
Icons.add_circle,
size: 30,
),
label: FittedBox(
child: Text(kQptBtnAddEventText),
),
),
NavigationRailDestination(
icon: LocationFlowWidget(),
label: FittedBox(
child: Text("Locations"),
),
),
],
onDestinationSelected: (index) async {
setState(() {
currentNavIndex = index;
});
switch (currentNavIndex) {
case 0:
{
/// PROFILE SCREEN
Navigator.popAndPushNamed(context, CalendarScreen.id);
}
break;
case 1:
{
ScaffoldMessengerState scaffoldState = ScaffoldMessenger.of(context);
final submitStatus = await SchedulerUtils.openCreateDialog(context, "${targetUser.fname} ${targetUser.lname}");
final scaffoldController = scaffoldState.showSnackBar(
SnackBar(
content: Text(submitStatus ?? "Closing the dialog..."),
),
);
}
break;
default:
{
/// TODO: filtering stuff based on location selected
print("locations was selected");
}
break;
}
},
selectedIndex: null),
),
),
Flexible(
flex: 12,
child: Padding(
padding: const EdgeInsets.only(
top: 20.0,
bottom: 20.0,
),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
const Text(
'Location Calendar',
style: TextStyle(fontSize: 28, color: Colors.blueGrey, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
Expanded(
child: MyCalendar(
inputCurrentUser: targetUser,
),
),
],
),
),
),
],
),
),
],
),
Location flow class that uses the Flow object:
const double buttonSize = 30;
class LocationFlowWidget extends StatefulWidget {
const LocationFlowWidget({Key? key}) : super(key: key);
@override
State<LocationFlowWidget> createState() => _LocationFlowWidgetState();
}
class _LocationFlowWidgetState extends State<LocationFlowWidget> {
@override
Widget build(BuildContext context) => Flow(
delegate: MyFlowDelegate(),
children: <IconData>[
Icons.mail,
].map<Widget>(buildItem).toList(),
);
/// this converts the icons into Floating action buttons
Widget buildItem(IconData icon) {
return Expanded(
child: SizedBox(
width: buttonSize,
height: buttonSize,
child: FloatingActionButton(
elevation: 0,
splashColor: Colors.black,
child: Icon(
icon,
color: Colors.white,
size: 30,
),
onPressed: () {
/// do stuff
},
),
),
);
}
}
class MyFlowDelegate extends FlowDelegate {
@override
void paintChildren(FlowPaintingContext context) {
/// This will tell Flutter where to draw each of Flows children
/// the i is the index within the list of children
context.paintChild(
0,
);
}
@override
bool shouldRepaint(covariant FlowDelegate oldDelegate) => false;
}
The error I'm getting is as follows: ======== Exception caught by widgets library ======================================================= The following assertion was thrown while applying parent data.: Incorrect use of ParentDataWidget.
The ParentDataWidget Expanded(flex: 1) wants to apply ParentData of type FlexParentData to a RenderObject, which has been set up to accept ParentData of incompatible type ParentData.
Usually, this means that the Expanded widget has the wrong ancestor RenderObjectWidget. Typically, Expanded widgets are placed directly inside Flex widgets. The offending Expanded is currently placed inside a RepaintBoundary widget.
The ownership chain for the RenderObject that received the incompatible parent data was: SizedBox ← Expanded ← RepaintBoundary-[<0>] ← Flow ← LocationFlowWidget ← IconTheme ← _AddIndicator ← Column ← Padding ← ConstrainedBox ← ⋯