android - Flutter:使用带有 BottomNavigationBar 的可扩展文本字段
问题描述
我需要一些关于这个布局的帮助:)
布局包含一个BottomNavigationBar
. 正文由Container
顶部的 a(用作某种标题)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),
),
]
)
)
],
),
),
),
);
},
);
但它抛出了一个异常。我尝试用aExpanded
和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),
),
),
],
),
),
),
);
},
);
}
}
推荐阅读
- android - 我的 android 模拟器的互联网是否因为我在热点上而无法工作?
- excel - Excel 中 INDEX 的替代方案
- swift - 为什么不能在方法中刷新文本字段?
- google-chrome - 使用浏览器访问 url
- function - 在 julia 函数中定义变量时,我在该行收到有关未定义变量的错误
- ios - IOS/Xcode:完成块中的断点可能吗?
- php - 尽管执行中提供了参数值,但语句不返回任何记录
- ios - 如何在 UITextView swift4 中居中 AttributedText 链接
- excel - 通过excel vba同时追加和更新访问
- java - 找到数字 600851475143L 的最大素数