我需要使用SingleChildScrollView
才能使用keyboard_actions以便我可以在iOS中的键盘顶部放置"完成"按钮(目前使用数字键盘)
SingleChildScrollView
将有一个列作为子列,然后有一个按钮放在底部。我尝试使用LayoutBuilder
来强制SingleChildScrollView
高度。
LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints:
BoxConstraints(minHeight: viewportConstraints.maxHeight),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Column(),
// Spacer() ?
FlatButton()
])));
});
我尝试使用带有maxHeight
属性的BoxConstraints
,但最终当键盘出现时,小部件不会吝啬
。旁注:脚手架的resizeToAvoidBottomInset
和resizeToAvoidBottomPadding
都设置为true
(默认值)
SingleChildScrollView
的问题在于它shrikwrap
它是孩子。 因此,要在两者之间使用自动调整大小的小部件 - 我们需要使用MediaQuery
来获取屏幕高度和SizedBox
展开 -SingleChildScrollView
。
这里的按钮将在屏幕底部。
工作代码:
double height = MediaQuery.of(context).size.height;
SingleChildScrollView(
child: SizedBox(
height: height,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Column(
children: <Widget>[
Text('Dummy'),
Text('Dummy'),
Text('Dummy'),
],
),
Spacer(),
FlatButton(
onPressed: () {},
child: Text('Demo'),
)
])),
)
选择的答案实际上不起作用,因为使用 SsizeBox 将列的最大大小限制为屏幕的高度,因此您不能在其中放置尽可能多的小部件(否则它们会在屏幕外而不会滚动)。
无论列中有许多小部件,此解决方案都将起作用: https://github.com/flutter/flutter/issues/18711#issuecomment-505791677
重要说明:仅当列中的小部件具有固定高度(例如,TextInputField 没有固定高度)时,它才有效。如果它们的高度可变,请用固定高度的容器包裹它们。
我只是在这里复制并粘贴了我找到的最佳解决方案,由@Quentin引用,由 @NikitaZhelonkin 在 Github 上的 Flutter 第 18711 期中详细说明。简直是完美的解决方案!
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('AppBar'),
),
body: LayoutBuilder(builder: (context, constraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(minWidth: constraints.maxWidth, minHeight: constraints.maxHeight),
child: IntrinsicHeight(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Text('header'),
Expanded(
child: Container(
color: Colors.green,
child: Text('body'),
),
),
Text('footer'),
]
),
)
)
);
})
);
}
}
最好的方法是使用 CustomScrollView 而不是 SingleChildScrollView。使用带高度的 SsizeBox 时,当小部件不适合并且需要滚动时,将发生图形错误。
CustomScrollView(
slivers: [
SliverFillRemaining(
hasScrollBody: false,
child: Colum..
您也可以使用此解决方法,您可以在SingleChildScrollView中使用填充属性,如下所示:
SingleChildScrollView(
padding: EdgeInsets.only(top: height),
child: yourWidgets(),
而高度是远离顶部的距离。
您还可以使用此行来获取移动屏幕高度:
double height = MediaQuery.of(context).size.height;
我为自己找到的最佳解决方案。
将小部件居中,并用填充从上到下推动它们。
return Scaffold(
resizeToAvoidBottomInset: true,
//resizeToAvoidBottomPadding: false,
backgroundColor: PrimaryColor,
body: Center(
SingleChildScrollView(child:
_body())));
Widget _body() {
return Padding(
padding: EdgeInsets.only(top: MediaQuery.of(context).size.height/2.7),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Visibility(
visible:
_userProvider.stateReqVMTokenSocial !=
StateReqVM.Processing,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
...
...
...
],
)),
Visibility(
visible:
_userProvider.stateReqVMTokenSocial ==
StateReqVM.Processing,
child: CircularProgressIndicator()),
Text(
'',
style: Theme.of(context).textTheme.headline4,
),
],
)
);
}
您只需在bottomNavigationBar中添加小部件,如下所示:
return Scaffold(
bottomNavigationBar: YOUR_WIDGET()
{...}