如何在 Flutter 中偏移脚手架小部件?
How can I offset a scaffold widget in Flutter?
我想设计一个如下所示的自定义导航window。
我计划:
- 创建我的导航小部件
- 创建我的新闻提要小部件
- 堆叠两个小部件(新闻提要在导航顶部)
- 如果单击菜单图标,将新闻源小部件转换为某个值,以便下方的导航小部件可见
我做了前三步。我对第四个有问题。我设置了一个 Offset 状态变量,并将脚手架小部件放置在 Positioned 小部件中。我将 Positioned class 的 'left' 设置为 Offset.dx.
代码:
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,),
),
);
}
}
抛出错误:
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): ════════════════════════════════════════════════════════════════════════════════════════════════════
问题:
- 我的方法正确吗?
- 如果正确,错误告诉我什么?
- 如果这不是正确的方法,是否有更简单或更好的方法来实现?
如果我对此有误,请告诉我,但听起来您希望导航抽屉在用户单击菜单按钮时打开。值得庆幸的是,Flutter 已经处理了这个问题!
您可以简单地使用脚手架的 drawer
属性。您将一个抽屉(或可能是另一个小部件)传递给它来显示,它会自动处理以使其可从左侧滑入。
如果您还想在按下按钮时打开它,您可以使用按钮中的 Scaffold.of(context).openDrawer();
。请注意,要获取包含脚手架的上下文,您必须使用 Builder 或使您的应用栏成为新的小部件。
经过一番研究,我在 YouTube 上找到了这个精彩的视频。它非常有用,完全解决了我的问题。
他使用了相同的方法,但代码要好得多。我会推荐任何正在学习 Flutter 的人观看他的所有视频。
Link 到视频 here。
包隐藏抽屉菜单
这些包使用起来非常简单。 Link 到包是 here。
我想设计一个如下所示的自定义导航window。
我计划:
- 创建我的导航小部件
- 创建我的新闻提要小部件
- 堆叠两个小部件(新闻提要在导航顶部)
- 如果单击菜单图标,将新闻源小部件转换为某个值,以便下方的导航小部件可见
我做了前三步。我对第四个有问题。我设置了一个 Offset 状态变量,并将脚手架小部件放置在 Positioned 小部件中。我将 Positioned class 的 'left' 设置为 Offset.dx.
代码:
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,), ), ); } }
抛出错误:
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): ════════════════════════════════════════════════════════════════════════════════════════════════════
问题:
- 我的方法正确吗?
- 如果正确,错误告诉我什么?
- 如果这不是正确的方法,是否有更简单或更好的方法来实现?
如果我对此有误,请告诉我,但听起来您希望导航抽屉在用户单击菜单按钮时打开。值得庆幸的是,Flutter 已经处理了这个问题!
您可以简单地使用脚手架的 drawer
属性。您将一个抽屉(或可能是另一个小部件)传递给它来显示,它会自动处理以使其可从左侧滑入。
如果您还想在按下按钮时打开它,您可以使用按钮中的 Scaffold.of(context).openDrawer();
。请注意,要获取包含脚手架的上下文,您必须使用 Builder 或使您的应用栏成为新的小部件。
经过一番研究,我在 YouTube 上找到了这个精彩的视频。它非常有用,完全解决了我的问题。
他使用了相同的方法,但代码要好得多。我会推荐任何正在学习 Flutter 的人观看他的所有视频。
Link 到视频 here。
包隐藏抽屉菜单
这些包使用起来非常简单。 Link 到包是 here。