Flutter - 如何使列屏幕可滚动
Posted
技术标签:
【中文标题】Flutter - 如何使列屏幕可滚动【英文标题】:Flutter - How to make a column screen scrollable 【发布时间】:2019-02-02 20:24:03 【问题描述】:我正在构建一个带有登录屏幕的颤振应用程序。专注于文本字段时,屏幕溢出,我无法滚动。我试过使用ListView.builder
,但这只会给出一个renderBox错误,并且常规的ListView
不起作用
小部件结构是这样的
-scafold
- body
- container
- column
- form
- column
- textInput
- textInput
- container
- container
- row
- raisedButton
提前谢谢你!!
【问题讨论】:
使用此参考***.com/questions/51997936/flutter-listview-overflow/… 我用 ListView 替换了第一列,它起作用了。如果您更喜欢使用 Listview,请使用 listview 添加示例并将错误粘贴到此处。否则,使用@Zulfiqar 的方式 【参考方案1】:ListView
解决方案应该可以工作,但在撰写本文时,它受到here 列出的崩溃的影响。另一种在不发生崩溃的情况下实现相同目标的方法是使用SingleChildScrollView
:
return new Container(
child: new SingleChildScrollView(
child: new Column(
children: <Widget>[
_showChild1(),
_showChild2(),
...
_showChildN()
]
)
)
);
【讨论】:
当我要滚动的列嵌套在另一列中时,此方法对我不起作用。它适用于滚动最外层的列。 只有小部件树中的第一个孩子使列垂直滚动。我想让整个项目滚动 我遇到了一些错误尝试添加``` mainAxisSize: MainAxisSize.min ``` 到你的Column
小部件。此外,如果子小部件是 ListView.builde
添加 shrinkWrap: true
【参考方案2】:
试试这个代码:它使用 ListView
class Home extends StatelessWidget
@override
Widget build(BuildContext context)
// TODO: implement build
return Scaffold(
body: Center(
child: ListView(
shrinkWrap: true,
padding: EdgeInsets.all(15.0),
children: <Widget>[
Center(
child: Card(
elevation: 8.0,
child: Container(
padding: EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(
prefixIcon: Icon(Icons.person),
labelText: "Username or Email",
),
),
SizedBox(
height: 15.0,
),
TextField(
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock),
labelText: "Password",
),
),
SizedBox(
height: 15.0,
),
Material(
borderRadius: BorderRadius.circular(30.0),
//elevation: 5.0,
child: MaterialButton(
onPressed: () => ,
minWidth: 150.0,
height: 50.0,
color: Color(0xFF179CDF),
child: Text(
"LOGIN",
style: TextStyle(
fontSize: 16.0,
color: Colors.white,
),
),
),
)
],
),
),
),
),
SizedBox(
height: 25.0,
),
Row(
children: <Widget>[
Expanded(child: Text("Don't Have a Account?")),
Text("Sign Up",
style: TextStyle(
color: Colors.blue,
)),
],
),
],
),
),
bottomNavigationBar: Padding(
padding: EdgeInsets.all(10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: RaisedButton(
padding: EdgeInsets.all(15.0),
onPressed: () ,
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
32.0,
),
side: BorderSide(color: Color(0xFF179CDF))),
child: Text(
"SKIP SIGN UP FOR NOW",
style:
TextStyle(fontSize: 18.0, color: Color(0xFF179CDF)),
),
)),
],
),
),
);
【讨论】:
shrinkWrap: true
是这个详尽答案中唯一重要的事情【参考方案3】:
有两种简单的方法可以做到这一点。
将您的Column
包裹在SingleChildScrollView
中
SingleChildScrollView(
child: Column(
children: [
Text('First'),
//... other children
Text('Last'),
],
),
)
使用ListView
而不是Column
。
ListView(
children: [
Text('First'),
//... other children
Text('Last'),
],
)
这种方法使用起来很简单,但是您会失去crossAxisAlignment
等功能以及Column
提供的其他好处,在这种情况下,您可以将您的子小部件包装在Align
中并设置对齐属性。
现在您可能有嵌套的子级,它们可以进一步滚动,在这种情况下,您需要为您的子级提供一个固定的高度,您可以使用SizedBox
,仅此而已。
例如:
ListView(
children: [
Text('First'),
SizedBox(
height: 100,
child: ListView(...), // nested ScrollView
),
Text('Last'),
],
)
【讨论】:
对我来说最完整和最容易理解的答案。 使用SingleChildScrollView
应该是实现这一目标的公认标准方式。
感谢分享此信息。能说说推荐哪一款吗?
@Aravin 好吧,这取决于您的用例,如果没有足够的项目并且您想要Column
的某些属性,那就去吧,否则ListView
更好。【参考方案4】:
当我们必须在屏幕上垂直列出小部件并且SingleChildScrollView
小部件为Column
小部件提供滚动功能时使用该列。
当我们使用SingleChildScrollView+Column 时,即使只有少数项目可见,也会呈现整个项目列表。
所以对于包含少量项目的复杂布局,性能提升可能不值得麻烦,在这种情况下我们可以使用SingleChildScrollView。
使用SingleChildScrollView
和Columns
使您的屏幕可滚动,并且您可以按照上述方式进行布局
几个优点:
-
当需要具有滚动功能的不同小部件时,它会很有用。
对于复杂的布局,当项目较少且性能不是问题时,我们可以使用它(就像每个其他小部件都需要一些不同于其他小部件的修改时)
这是你怎么做的
class MyHome extends StatelessWidget
@override
Widget build(BuildContext context)
// TODO: implement build
return Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
bottom: false,
child: Container(
padding: EdgeInsets.only(left: 15, right: 15),
height: double.infinity,
width: double.infinity,
child: SingleChildScrollView(
padding: EdgeInsets.only(bottom: 15),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 200.0,
),
Card(
elevation: 8.0,
child: Container(
padding: EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(
prefixIcon: Icon(Icons.person),
labelText: "Username or Email",
),
),
SizedBox(
height: 15.0,
),
TextField(
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock),
labelText: "Password",
),
),
SizedBox(
height: 30.0,
),
MaterialButton(
height: 50.0,
elevation: 5,
minWidth: 300,
onPressed: () ,
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
),
color: Theme.of(context).primaryColor,
disabledColor: Theme.of(context)
.primaryColor
.withOpacity(0.50),
disabledElevation: 0,
child: Text('SIGN IN',
textAlign: TextAlign.center, style: TextStyle(color: Colors.white),))
],
),
),
),
SizedBox(
height: 25.0,
),
Row(
children: <Widget>[
Expanded(child: Text("Don't Have a Account?")),
Text("Sign Up",
style: TextStyle(
color: Colors.blue,
)),
],
),
SizedBox(
height: 50.0,
),
Align(
alignment: Alignment.bottomCenter,
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
Text(
'New to App?',
style: TextStyle(color: Colors.black87),
),
SizedBox(
width: 5,
),
GestureDetector(
onTap: ()
,
child: Text(
"REGISTER", style: TextStyle(
color: Colors.blue,
)
),
),
]),
)
],
)),
),
));
【讨论】:
你是一个完整的复印机老兄,这次你复制了this的答案。我看到你几乎 95% 的答案都是从别人那里抄来的。 是的,我同意,但我已尝试使用已提出问题的 UI 进行扩展。【参考方案5】:我们可以使用 Expanded 小部件。它将添加滚动。
return new Expanded(
child: new SingleChildScrollView(
child: new Column(
children: <Widget>[
_showChild1(),
_showChild2(),
...
_showChildN()
]
)
)
);
【讨论】:
【参考方案6】:将您的列包装在 SingleChildScrollView 中,然后将 SingleChildScrollView 包装在 Center 小部件中以使小部件在列中居中。
Center(
child: SingleChildScrollView(
child: Column(
children: [
Text('First'),
//... other children
Text('Last'),
],
),
)
【讨论】:
以上是关于Flutter - 如何使列屏幕可滚动的主要内容,如果未能解决你的问题,请参考以下文章
在屏幕上添加按钮而不使用 MaterialApp Flutter
如何在 Flutter 中让 ListView 中的项目覆盖整个屏幕
Flutter 可滚动组件 之 SingleChildScrollView (十五)