如何在颤动中滚动页面
Posted
技术标签:
【中文标题】如何在颤动中滚动页面【英文标题】:How to scroll page in flutter 【发布时间】:2019-01-16 19:19:37 【问题描述】:我的页面代码是这样的。我需要滚动应用栏下方的部分。
@override
Widget build(BuildContext context)
return new Scaffold(
appBar: new AppBar(... ),
body: new Stack(
children: <Widget>[
new Container(
decoration: BoxDecoration(
image: DecorationImage(...),
new Column(children: [
new Container(...),
new Container(...... ),
new Padding(
child: SizedBox(
child: RaisedButton(..),
),
new Divider(),
new Column(
children: <Widget>[
new Container(
child: new Row(
children: <Widget>[
new Expanded(
child: new Text( ),
),
new IconButton(
icon: IconButton(..),
onPressed: ()
_changed(true, "type");
,
),
],
),
),
visibilityPropertyType
? new Container(
margin: EdgeInsets.all(24.0),
child: new Column(
children: <Widget>[
new Row(
children: <Widget>[
new Expanded(... ),
new RaisedButton(..)
],
),
new Padding(
padding: const EdgeInsets.only(top: 10.0),
child: new Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: <Widget>[
new Column(
children: <Widget>[
new Row(
children: <Widget>[.. ]),
new Row(
children: <Widget>[]),
new Row(
children: <Widget>[]),
new Row(
children: <Widget>[],
),
new Column(
children: <Widget>[
new Row(
children: <Widget>[],
),
],
),
],
),
),
],
))
: new Container(),
],
),
new Divider(
color: Colors.white,
)
])
],
),
);
我需要让身体部分可滚动。我怎样才能实现那个滚动。
如果存在任何自定义滚动方法。我尝试过Scrollable
和SingleChildScrollView
,但不能满足我的需求。
当我使用SinglechildScrollView
时,会出现错误 BoxConstraints 强制无限高度。如果我删除了 LayoutBuilder 它会导致 A RenderFlex overflowed by 22 pixels on the bottom
错误
【问题讨论】:
【参考方案1】:将您的小部件树包装在 SingleChildScrollView 中
body: SingleChildScrollView(
child: Stack(
children: <Widget>[
new Container(
decoration: BoxDecoration(
image: DecorationImage(...),
new Column(children: [
new Container(...),
new Container(...... ),
new Padding(
child: SizedBox(
child: RaisedButton(..),
),
....
...
); // Single child scroll view
记住,SingleChildScrollView 只能有一个直接的小部件(就像 android 中的 ScrollView)
【讨论】:
RenderFlex children have non-zero flex but incoming height constraints are unbounded.
让我崩溃
你是在使用 ListView 还是 SingleChildScrollView 中可滚动的东西?如果是,则将该小部件的 shringWrap 属性设置为 true 可能会解决此问题。
如果您有 Expanded,请尝试删除。
很高兴我遇到了堆栈溢出。谷歌建议使用 DraggableScrollableSheet。这看起来有点像更多的工作,而不是完全需要的。 +1 堆栈溢出。【参考方案2】:
感谢大家的帮助。根据您的建议,我找到了这样的解决方案。
new LayoutBuilder(
builder:
(BuildContext context, BoxConstraints viewportConstraints)
return SingleChildScrollView(
child: ConstrainedBox(
constraints:
BoxConstraints(minHeight: viewportConstraints.maxHeight),
child: Column(children: [
// remaining stuffs
]),
),
);
,
)
【讨论】:
LayoutBuilder + BoxConstraints + ConstrainedBox - 创造奇迹!例如,在我的例子中,我想要一个嵌套在列中的水平滚动条。问题是默认情况下,无论您做什么,水平滚动都会将其内容居中。所以我不得不把 SingleChildScrollView 放在一个带 maxWidth 的 ConstrainedBox 中:viewportConstraints.maxWidth,minWidth:viewportConstraints.maxWidth。因此,如果有一些内容 - 它会向左对齐,如果有很多内容(超过屏幕宽度)它就会开始滚动。 此解决方案有效,但布局构建器会在与页面有任何交互时继续构建所有所有小部件,例如滚动列表、单击按钮。好吗?如果您想检查它是否重建,您可以从 pub 加载 randomColor 库并将其分配给页面中的任何小部件。您尝试与布局构建器下的任何小部件进行交互。您可以看到分配了 randomColor 的小部件每次都会改变颜色。好吗??需要专家建议。 Layout Builder 会在与任何子窗口小部件有任何交互时重新排列子窗口。 这个答案对我来说是一个小奇迹。我一直在努力使可滚动列表伸展以匹配堆栈中最大子项的高度。您的代码示例有助于完成这项工作。谢谢!【参考方案3】:在页面中添加滚动的两种方式
1.使用 SingleChildScrollView :
SingleChildScrollView(
child: Column(
children: [
Container(....),
SizedBox(...),
Container(...),
Text(....)
],
),
),
2。使用 ListView : ListView 是默认提供 Scroll 无需添加额外的小部件进行滚动
ListView(
children: [
Container(..),
SizedBox(..),
Container(...),
Text(..)
],
),
【讨论】:
【参考方案4】:你可以试试CustomScrollView
。将您的 CustomScrollView 放在 Column Widget 中。
举个例子-
class App extends StatelessWidget
App(Key key): super(key: key);
@override
Widget build(BuildContext context)
return new Scaffold(
appBar: AppBar(
title: const Text('AppBar'),
),
body: new Container(
constraints: BoxConstraints.expand(),
decoration: new BoxDecoration(
image: new DecorationImage(
alignment: Alignment.topLeft,
image: new AssetImage('images/main-bg.png'),
fit: BoxFit.cover,
)
),
child: new Column(
children: <Widget>[
Expanded(
child: new CustomScrollView(
scrollDirection: Axis.vertical,
shrinkWrap: false,
slivers: <Widget>[
new SliverPadding(
padding: const EdgeInsets.symmetric(vertical: 0.0),
sliver: new SliverList(
delegate: new SliverChildBuilderDelegate(
(context, index) => new YourRowWidget(),
childCount: 5,
),
),
),
],
),
),
],
)),
);
在上面的代码中,我在 CustomScrollView 中显示了一个项目列表(总共 5 个)。
YourRowWidget
小部件作为列表项呈现 5 次。一般来说,你应该根据一些数据来渲染每一行。
你可以移除 Container 小部件的装饰属性,它只是为了提供背景图片。
【讨论】:
【参考方案5】:您可以使用这个,这是最佳实践。
SingleChildScrollView( child: Column( children: <Widget>[ //Your Widgets //Your Widgets, //Your Widgets ], ), );
【讨论】:
【参考方案6】:使用LayoutBuilder
得到你想要的输出
用LayoutBuilder
包装SingleChildScrollView
并实现Builder函数。
我们可以使用LayoutBuilder
获取框contains
或可用空间量。
LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints)
return SingleChildScrollView(
child: Stack(
children: <Widget>[
Container(
height: constraints.maxHeight,
),
topTitle(context),
middleView(context),
bottomView(context),
],
),
);
)
【讨论】:
【参考方案7】:如果你已经在使用 statelessWidget 就很容易签出我的代码
class _MyThirdPage extends StatelessWidget
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text('Understanding Material-Cards'),
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
_buildStack(),
_buildCard(),
SingleCard(),
_inkwellCard()
],
)),
);
【讨论】:
【参考方案8】:看看这个,可能对你有帮助。
class ScrollView extends StatelessWidget
@override
Widget build(BuildContext context)
return new LayoutBuilder(
builder:
(BuildContext context, BoxConstraints viewportConstraints)
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: viewportConstraints.maxHeight),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Hello world!!"),
//You can add another children
]),
),
);
,
);
【讨论】:
【参考方案9】:您可以通过两种方式滚动内容的任何部分...
-
您可以直接使用列表视图
或 SingleChildScrollView
大多数情况下,当特定屏幕中有键盘输入时,我会直接使用列表视图,这样内容就不会被键盘重叠,并且更多地滚动到顶部....
这个技巧会有用很多次....
【讨论】:
以上是关于如何在颤动中滚动页面的主要内容,如果未能解决你的问题,请参考以下文章