我需要有关此布局的帮助:)
布局包含BottomNavigationBar
。主体由顶部的Container
(用作某种标头)和Textfield
的下面的Container
组成。 Textfield
应该展开以填充剩余的空间。一旦用户输入了足够多的行以使文本无法显示在屏幕上,整个正文(Textfield
和Container
)应变为scrollable
。
因此,它基本上是一个笔记应用程序,具有Header
(Container
部分)和多个Tabs
用于记录笔记。
到目前为止,这是解决方案:
Scaffold buildBody(BuildContext context) {
return Scaffold(
appBar: AppBar(...),
body: _buildScaffoldBody(),
bottomNavigationBar: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
AnimatedCrossFade(
firstChild: Material(
color: Theme.of(context).primaryColor,
child: TabBar(
controller: _tabController,
tabs: _tabNames,
onTap: (int) {
...
},
),
),
secondChild: Container(),
crossFadeState: _screen == 0
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: const Duration(milliseconds: 300),
),
],
),
);
}
Widget _buildScaffoldBody() {
return LayoutBuilder(
builder: (context, constraint) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: constraint.maxHeight),
child: IntrinsicHeight(
child: Column(
children: <Widget>[
Container(
height: 100,
alignment: Alignment.center,
color: Colors.green,
child: Text("Header"),
),
Expanded( //This is probably the cause
child: TabBarView( //of the exception
controller: _tabController,
children: <Widget>[
TextField(
expands: true,
maxLines: null,
decoration: InputDecoration(
fillColor: Colors.blue[200], filled: true),
),
TextField(
expands: true,
maxLines: null,
decoration: InputDecoration(
fillColor: Colors.blue[200], filled: true),
),
TextField(
expands: true,
maxLines: null,
decoration: InputDecoration(
fillColor: Colors.blue[200], filled: true),
),
]
)
)
],
),
),
),
);
},
);
但是它引发了异常。我尝试将Expanded
替换为Container
,并对height
和width
进行硬编码。如果这样做,则不会引发异常,但是Textfield
不再是expandable
,并且不会与Header
一起滚动。它仅在包裹Container
的Textfield
中滚动。
The following assertion was thrown during performLayout():
I/flutter ( 8080): RenderViewport does not support returning intrinsic dimensions.
I/flutter ( 8080): Calculating the intrinsic dimensions would require instantiating every child of the viewport, which
I/flutter ( 8080): defeats the point of viewports being lazy.
I/flutter ( 8080): If you are merely trying to shrink-wrap the viewport in the main axis direction, consider a
I/flutter ( 8080): RenderShrinkWrappingViewport render object (ShrinkWrappingViewport widget), which achieves that
I/flutter ( 8080): effect without implementing the intrinsic dimension API.
I/flutter ( 8080):
I/flutter ( 8080): The relevant error-causing widget was:
I/flutter ( 8080): IntrinsicHeight
您只是放错了一些东西。尽力将代码分解成可重用的小部件。它有助于保持一切井井有条。
此外,通常,当您尝试实现一些常用的东西时,很可能已经为它构建了一个小部件。在这种情况下,您无需弄乱AnimatedCrossFade
等...它们全都内置在TabBarView
中。
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
home: TabBarScaffold(),
);
}
}
class TabBarScaffold extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
color: Colors.yellow,
home: DefaultTabController(
length: 3,
child: new Scaffold(
body: MyPages(),
bottomNavigationBar: MyTabs(),
),
),
);
}
}
class MyTabs extends StatelessWidget {
@override
Widget build(BuildContext context) {
return TabBar(
tabs: [
Tab(
child: Text("Tab 1"),
),
Tab(
child: Text("Tab 2"),
),
Tab(
child: Text("Tab 3"),
),
],
labelColor: Colors.blue,
unselectedLabelColor: Colors.black,
indicatorSize: TabBarIndicatorSize.label,
indicatorPadding: EdgeInsets.all(5.0),
indicatorColor: Colors.red,
);
}
}
class MyPages extends StatelessWidget {
@override
Widget build(BuildContext context) {
return TabBarView(
children: [
MyPageBody(
textBackgroundColor: Colors.blue[200],
),
MyPageBody(
textBackgroundColor: Colors.green[200],
),
MyPageBody(
textBackgroundColor: Colors.red[200],
),
],
);
}
}
class MyPageBody extends StatelessWidget {
final Color textBackgroundColor;
MyPageBody({this.textBackgroundColor});
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraint) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: constraint.maxHeight),
child: IntrinsicHeight(
child: Column(
children: <Widget>[
Container(
height: 100,
alignment: Alignment.center,
color: Colors.green,
child: Text("Header"),
),
Expanded(
child: TextField(
expands: true,
maxLines: null,
decoration: InputDecoration(
fillColor: textBackgroundColor, filled: true),
),
),
],
),
),
),
);
},
);
}
}