I want to design a custom navigation window like the one below.
I planned to:
- Create my navigation widget
- Create my news feed widget
- Stack both widgets (news feed on top of the navigation)
- If the menu icon is clicked, translate the news feed widget to some value so that the underneath nav widget is visible
I did the first three steps. I have problems with the fourth one. I set an Offset state variable and placed my scaffold widget within a Positioned widget. I set the 'left' of the Positioned class to Offset.dx.
Code:
import 'package:flutter/material.dart';
import 'package:flutter/animation.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: const MaterialColor(0xfff06000, const {
50: const Color(0xfffff0e6),
100: const Color(0xffffd1b3),
200: const Color(0xffffb380),
300: const Color(0xffff944d),
400: const Color(0xffff751a),
500: const Color(0xfff06000),
600: const Color(0xffcc5200),
700: const Color(0xffb34700),
800: const Color(0xff993d00),
900: const Color(0xff662900),
})),
//I stack the classes
home: new Stack(
children: [
new MyNavPage(),
new MyHomePage(title: "Home",initialOffset: new Offset(0.0, 0.0),),
],
)
);
}
}
// This is my news feed class
class MyHomePage extends StatefulWidget {
final String title;
final Offset initialOffset;
MyHomePage({Key key, this.title, this.initialOffset}) : super(key: key);
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State with TickerProviderStateMixin {
Offset position = new Offset(0.0, 0.0);
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
void initState() {
super.initState();
position = widget.initialOffset;
}
@override
Widget build(BuildContext context) {
final scaffold = new Scaffold(
primary: true,
appBar: new AppBar(
title: new Text(widget.title),
centerTitle: true,
leading: new IconButton(icon: new Icon(Icons.menu),onPressed: () => setState(() => position = new Offset(100.0, 0.0)),),
),
backgroundColor: Colors.white30,
body: new Container(
child: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
new Text(
'You have pushed the button this many times:',
),
new Text(
'$_counter',
style: Theme
.of(context)
.textTheme
.display1,
),
],
),
),
),
floatingActionButton: new FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: new Icon(Icons.add),
),
);
return new Positioned(
left: position.dx,
child:scaffold,
);
}
}
// My navigation class. It has those navigation options as a column to the left.
// The width is 100.0, hence I offset my home page by 100.0
class MyNavPage extends StatefulWidget {
MyNavPage({Key key}) : super(key: key);
@override
_MyNavPageState createState() => new _MyNavPageState();
}
class _MyNavPageState extends State {
@override
Widget build(BuildContext context) {
Expanded createNavChild(Icon i, Text t) {
return new Expanded(
child: new GestureDetector(
child: new Container(
width: 100.0,
decoration: new BoxDecoration(color: Colors.red,),
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
i,
t
],
),
),
),
);
}
return new Scaffold(
primary: true,
body: new Container(
margin: MediaQuery
.of(context)
.padding,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
createNavChild(new Icon(Icons.home, size: 30.0), new Text("Home")),
createNavChild(
new Icon(Icons.person_add, size: 30.0), new Text("Register")),
createNavChild(
new Icon(Icons.search, size: 30.0), new Text("Player Search")),
createNavChild(
new Icon(Icons.event, size: 30.0), new Text("Events")),
createNavChild(new Icon(Icons.file_download, size: 30.0),
new Text("Downloads")),
createNavChild(
new Icon(Icons.call, size: 30.0), new Text("Contact")),
],
),
decoration: new BoxDecoration(color: Colors.transparent,),
),
);
}
}
An error is thrown:
I/flutter ( 3090): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════ I/flutter ( 3090): The following assertion was thrown during performLayout(): I/flutter ( 3090): RenderCustomMultiChildLayoutBox object was given an infinite size during layout. I/flutter ( 3090): This probably means that it is a render object that tries to be as big as possible, but it was put I/flutter ( 3090): inside another render object that allows its children to pick their own size. I/flutter ( 3090): The nearest ancestor providing an unbounded width constraint is: I/flutter ( 3090): RenderStack#df1fd NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): creator: Stack ← Semantics ← Builder ← RepaintBoundary-[GlobalKey#274fe] ← IgnorePointer ← I/flutter ( 3090): FadeTransition ← FractionalTranslation ← SlideTransition ← _MountainViewPageTransition ← I/flutter ( 3090): AnimatedBuilder ← RepaintBoundary ← _FocusScopeMarker ← ⋯ I/flutter ( 3090): parentData: (can use size) I/flutter ( 3090): constraints: BoxConstraints(w=360.0, h=640.0) I/flutter ( 3090): size: Size(360.0, 640.0) I/flutter ( 3090): alignment: AlignmentDirectional.topStart I/flutter ( 3090): textDirection: ltr I/flutter ( 3090): fit: loose I/flutter ( 3090): overflow: clip I/flutter ( 3090): The nearest ancestor providing an unbounded height constraint is: I/flutter ( 3090): RenderStack#df1fd NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): creator: Stack ← Semantics ← Builder ← RepaintBoundary-[GlobalKey#274fe] ← IgnorePointer ← I/flutter ( 3090): FadeTransition ← FractionalTranslation ← SlideTransition ← _MountainViewPageTransition ← I/flutter ( 3090): AnimatedBuilder ← RepaintBoundary ← _FocusScopeMarker ← ⋯ I/flutter ( 3090): parentData: (can use size) I/flutter ( 3090): constraints: BoxConstraints(w=360.0, h=640.0) I/flutter ( 3090): size: Size(360.0, 640.0) I/flutter ( 3090): alignment: AlignmentDirectional.topStart I/flutter ( 3090): textDirection: ltr I/flutter ( 3090): fit: loose I/flutter ( 3090): overflow: clip I/flutter ( 3090): The constraints that applied to the RenderCustomMultiChildLayoutBox were: I/flutter ( 3090): BoxConstraints(unconstrained) I/flutter ( 3090): The exact size it was given was: I/flutter ( 3090): Size(Infinity, Infinity) I/flutter ( 3090): See https://flutter.io/layout/ for more information. I/flutter ( 3090): When the exception was thrown, this was the stack: I/flutter ( 3090): #0 RenderBox.debugAssertDoesMeetConstraints. (package:flutter/src/rendering/box.dart:1698:9) I/flutter ( 3090): #1 RenderBox.debugAssertDoesMeetConstraints (package:flutter/src/rendering/box.dart:1772:6) I/flutter ( 3090): #2 RenderBox.size=. (package:flutter/src/rendering/box.dart:1507:17) I/flutter ( 3090): #3 RenderBox.size= (package:flutter/src/rendering/box.dart:1507:65) I/flutter ( 3090): #4 RenderCustomMultiChildLayoutBox.performLayout (package:flutter/src/rendering/custom_layout.dart:354:5) I/flutter ( 3090): #5 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #6 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #7 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #8 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #9 _RenderCustomClip.performLayout (package:flutter/src/rendering/proxy_box.dart:1141:11) I/flutter ( 3090): #10 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #11 RenderStack.performLayout (package:flutter/src/rendering/stack.dart:553:15) I/flutter ( 3090): #12 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #13 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #14 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #15 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #16 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #17 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #18 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #19 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #20 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #21 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #22 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #23 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #24 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #25 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #26 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #27 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #28 RenderOffstage.performLayout (package:flutter/src/rendering/proxy_box.dart:2712:13) I/flutter ( 3090): #29 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #30 RenderStack.performLayout (package:flutter/src/rendering/stack.dart:514:15) I/flutter ( 3090): #31 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #32 __RenderTheatre&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #33 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #34 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #35 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #36 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #37 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #38 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #39 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #40 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:107:13) I/flutter ( 3090): #41 RenderObject.layout (package:flutter/src/rendering/object.dart:1570:7) I/flutter ( 3090): #42 RenderView.performLayout (package:flutter/src/rendering/view.dart:125:13) I/flutter ( 3090): #43 RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1445:7) I/flutter ( 3090): #44 PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:709:18) I/flutter ( 3090): #45 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:270:19) I/flutter ( 3090): #46 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:627:13) I/flutter ( 3090): #47 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:208:5) I/flutter ( 3090): #48 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15) I/flutter ( 3090): #49 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9) I/flutter ( 3090): #50 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.scheduleWarmUpFrame. (package:flutter/src/scheduler/binding.dart:751:7) I/flutter ( 3090): #52 _Timer._runTimers (dart:isolate/runtime/libtimer_impl.dart:382:19) I/flutter ( 3090): #53 _Timer._handleMessage (dart:isolate/runtime/libtimer_impl.dart:416:5) I/flutter ( 3090): #54 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:165:12) I/flutter ( 3090): (elided one frame from package dart:async) I/flutter ( 3090): The following RenderObject was being processed when the exception was fired: I/flutter ( 3090): RenderCustomMultiChildLayoutBox#04aef relayoutBoundary=up3 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): creator: CustomMultiChildLayout ← AnimatedBuilder ← DefaultTextStyle ← AnimatedDefaultTextStyle ← I/flutter ( 3090): _InkFeatures-[GlobalKey#64807 ink renderer] ← NotificationListener ← I/flutter ( 3090): PhysicalModel ← AnimatedPhysicalModel ← Material ← PrimaryScrollController ← _ScaffoldScope ← I/flutter ( 3090): Scaffold ← ⋯ I/flutter ( 3090): parentData: (can use size) I/flutter ( 3090): constraints: BoxConstraints(unconstrained) I/flutter ( 3090): size: Size(Infinity, Infinity) I/flutter ( 3090): This RenderObject had the following descendants (showing up to depth 5): I/flutter ( 3090): RenderPositionedBox#4ac32 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderFlex#a08f4 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderParagraph#eba89 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderParagraph#5afd6 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderConstrainedBox#0b71f NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderPhysicalModel#fa853 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): _RenderInkFeatures#45d75 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderPositionedBox#7bd87 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderPadding#3faff NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderStack#4eccb NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderTransform#16934 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderTransform#317f7 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderSemanticsAnnotations#f02cf NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): RenderConstrainedBox#75c14 NEEDS-LAYOUT NEEDS-PAINT I/flutter ( 3090): ════════════════════════════════════════════════════════════════════════════════════════════════════
Questions:
- Is my approach correct?
- If it is correct, what is the error telling me?
- If it is not the right approach, is there a simpler or better way to achieve this?



new MyNavPage()at the start of thebuildmethod? Have you tried using/extending a standard app drawer withScaffoldand changing the width?