如何将 Widget 定位在 SingleChildScrollView 的底部?
How to position a Widget at the bottom of a SingleChildScrollView?
我需要使用 SingleChildScrollView
才能使用 keyboard_actions 以便我可以在 iOS 中的键盘顶部放置一个 "Done" 按钮(目前正在使用数字键盘)
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()
])));
});
我尝试将 BoxConstraints
与 maxHeight
属性一起使用,但最终小部件不会在键盘出现时向上滚动。
旁注:脚手架的 resizeToAvoidBottomInset
和 resizeToAvoidBottomPadding
都设置为 true
(默认值)
SingleChildScrollView
的问题在于它 shrikwrap
它是 children。
因此,要在两者之间设置自动调整大小的小部件 - 我们需要使用 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'),
)
])),
)
选择的答案实际上不起作用,因为使用 SizedBox 将 Column 的最大尺寸限制为屏幕的高度,因此您不能在其中放置任意数量的小部件(否则它们会离开屏幕而不可滚动)。
无论列中有多少小部件,此解决方案都有效:
https://github.com/flutter/flutter/issues/18711#issuecomment-505791677
重要说明:它仅在列中的小部件具有固定高度时才有效(例如 TextInputField 没有固定高度)。如果它们的高度可变,则用固定高度的 Container 包裹它们。
您也可以使用此解决方法,您可以像这样在 SingleChildScrollView 中使用填充属性:
SingleChildScrollView(
padding: EdgeInsets.only(top: height),
child: yourWidgets(),
而高度是距离顶部的距离。
您还可以使用此行获取移动屏幕高度:
double height = MediaQuery.of(context).size.height;
我刚刚复制并粘贴了我找到的最佳解决方案,引用自@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'),
]
),
)
)
);
})
);
}
}
我为自己找到的最佳解决方案。
将小部件居中并使用填充从上到下推动它们。
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,
),
],
)
);
}
我需要使用 SingleChildScrollView
才能使用 keyboard_actions 以便我可以在 iOS 中的键盘顶部放置一个 "Done" 按钮(目前正在使用数字键盘)
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()
])));
});
我尝试将 BoxConstraints
与 maxHeight
属性一起使用,但最终小部件不会在键盘出现时向上滚动。
旁注:脚手架的 resizeToAvoidBottomInset
和 resizeToAvoidBottomPadding
都设置为 true
(默认值)
SingleChildScrollView
的问题在于它 shrikwrap
它是 children。
因此,要在两者之间设置自动调整大小的小部件 - 我们需要使用 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'),
)
])),
)
选择的答案实际上不起作用,因为使用 SizedBox 将 Column 的最大尺寸限制为屏幕的高度,因此您不能在其中放置任意数量的小部件(否则它们会离开屏幕而不可滚动)。
无论列中有多少小部件,此解决方案都有效: https://github.com/flutter/flutter/issues/18711#issuecomment-505791677
重要说明:它仅在列中的小部件具有固定高度时才有效(例如 TextInputField 没有固定高度)。如果它们的高度可变,则用固定高度的 Container 包裹它们。
您也可以使用此解决方法,您可以像这样在 SingleChildScrollView 中使用填充属性:
SingleChildScrollView(
padding: EdgeInsets.only(top: height),
child: yourWidgets(),
而高度是距离顶部的距离。
您还可以使用此行获取移动屏幕高度:
double height = MediaQuery.of(context).size.height;
我刚刚复制并粘贴了我找到的最佳解决方案,引用自@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'),
]
),
)
)
);
})
);
}
}
我为自己找到的最佳解决方案。
将小部件居中并使用填充从上到下推动它们。
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,
),
],
)
);
}