我对扑扑很陌生。我想设计一个自定义的导航窗口,如下所示。
我计划要做的是:
我做了前3个步骤。我对第四个有问题。我设置了一个偏移状态变量,并将脚手架小部件放置在“位置”小部件中。我将Positioned类的“左侧”设置为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): ════════════════════════════════════════════════════════════════════════════════════════════════════
问题: 1.我的方法正确吗? 2.如果正确,那么错误告诉我什么? 3.如果不是正确的方法,是否有更简单或更佳的方法来实现这一目标?
答案 0 :(得分:4)
答案 1 :(得分:2)
让我知道我是否对此有错,但这听起来像是您希望在用户单击菜单按钮时打开导航抽屉。幸运的是,颤振已经可以解决这个问题!
您可以简单地使用脚手架的drawer
属性。您将其传递给抽屉(或可能的其他小部件)进行显示,它将自动处理使其可从左侧滑动。
如果您还想通过按钮打开它,则可以通过按钮使用Scaffold.of(context).openDrawer();
。请注意,要获取包含支架的上下文,您必须使用Builder或将您的应用栏设置为新的小部件。
答案 2 :(得分:2)
您可以使用以下方法实现此目的:flutter_inner_drawer
将此添加到您程序包的pubspec.yaml文件中:
dependencies:
flutter_inner_drawer: "^0.5.7+2"
简单用法
import 'package:flutter_inner_drawer/inner_drawer.dart';
.
.
.
@override
Widget build(BuildContext context)
{
return InnerDrawer(
key: _innerDrawerKey,
onTapClose: true, // default false
swipe: true, // default true
colorTransitionChild: Color.red, // default Color.black54
colorTransitionScaffold: Color.black54, // default Color.black54
//When setting the vertical offset, be sure to use only top or bottom
offset: IDOffset.only(bottom: 0.05, right: 0.0, left: 0.0),
scale: IDOffset.horizontal( 0.8 ), // set the offset in both directions
proportionalChildArea : true, // default true
borderRadius: 50, // default 0
leftAnimationType: InnerDrawerAnimation.static, // default static
rightAnimationType: InnerDrawerAnimation.quadratic,
backgroundDecoration: BoxDecoration(color: Colors.red ), // default Theme.of(context).backgroundColor
//when a pointer that is in contact with the screen and moves to the right or left
onDragUpdate: (double val, InnerDrawerDirection direction) {
// return values between 1 and 0
print(val);
// check if the swipe is to the right or to the left
print(direction==InnerDrawerDirection.start);
},
innerDrawerCallback: (a) => print(a), // return true (open) or false (close)
leftChild: Container(), // required if rightChild is not set
rightChild: Container(), // required if leftChild is not set
// A Scaffold is generally used but you are free to use other widgets
// Note: use "automaticallyImplyLeading: false" if you do not personalize "leading" of Bar
scaffold: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false
),
)
/* OR
CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
automaticallyImplyLeading: false
),
),
*/
)
}
// Current State of InnerDrawerState
final GlobalKey<InnerDrawerState> _innerDrawerKey = GlobalKey<InnerDrawerState>();
void _toggle()
{
_innerDrawerKey.currentState.toggle(
// direction is optional
// if not set, the last direction will be used
//InnerDrawerDirection.start OR InnerDrawerDirection.end
direction: InnerDrawerDirection.end
);
}
答案 3 :(得分:0)