Column
组件默认占用全部可用高度,Row
组件默认占用全部可用宽度。
Column
, Row
默认不具有滚动功能,当屏幕尺寸不能容纳组件时,将产生溢出:
增加滚动功能方法
方法1,使用 SingleChildScrollView
wrap body 相关组件
vs code: 选定需要增加滚动功能的 Column
或者 Row
, 鼠标左键 -> refactor -> Wrap with widget,然后将名称 widget
改为 SingleChildScrollView
:
SingleChildScrollView
实现列表的滚动功能,不再产生溢出:
body: SingleChildScrollView(
child: Column(
// mainAxisAlignment: MainAxisAlignment.spaceAround,
// crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: double.infinity,
child: Card(
color: Colors.blue,
child: Text('CHART'),
elevation: 5,
),
),
UserTransactions(),
],
),
));
方法2,使用 SingleChildScrollView
wrap子组件
取消方法1中增加的 SingleChildScrollView
,将要增加滚动功能的组件wrap 在 Container
组件里,设置 Container
的size,然后将 Column
wrap 在 SingleChildScrollView
里:
@override
Widget build(BuildContext context) {
return Container(
height: 300, // 如果此 heigt足够大,将产生溢出。
child: SingleChildScrollView(
child: Column(
children: transactions.map((tx) {
return Card(
child: Row(
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(
vertical: 10,
horizontal: 10,
),
为了取消用户输入时出现的溢出,在 body 里增加 SingleChildScrollView
,同方法1:
body: SingleChildScrollView(
child: Column(
// mainAxisAlignment: MainAxisAlignment.spaceAround,
// crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: double.infinity,
child: Card(
color: Colors.blue,
child: Text('CHART'),
elevation: 5,
),
),
方法3,使用 ListView
组件
使用 ListView
取代 SingleChildScrollView
+ Column
,因为可滚动的列表十分常见,因此使用 ListView
作为捷径,代码更简洁。
将代码中的 Column
直接替换成 ListView
:
Widget build(BuildContext context) {
return Container(
height: 300,
child: ListView(
children: transactions.map((tx) {
return Card(
child: Row(
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(
vertical: 10,
horizontal: 10,
),
ListView
组件有两种构造函数:
ListView(children: [])
ListView.builder()
当列表的items 足够多,必定有一部分 items 不可见,二者之间的区别是,ListView.builder()
进行了优化,使用懒惰加载的方式,只加载可见的 items,而 ListView(children: [])
则可见不可见的 items 全部加载,这将影响 performance。
所以,当列表很大或长度未知时,选择ListView.builder()
。
使用 ListView(children: [])
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../models/transaction.dart';
class TransactionList extends StatelessWidget {
final List<Transaction> transactions;
TransactionList(this.transactions);
@override
Widget build(BuildContext context) {
return Container(
height: 300,
child: ListView(
children: transactions.map((tx) {
return Card(
child: Row(
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(
vertical: 10,
horizontal: 10,
),
decoration: BoxDecoration(
border: Border.all(
color: Colors.purple,
width: 2,
),
),
padding: EdgeInsets.all(10),
child: Text('\$${tx.amount}',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.purple,
)),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
tx.title,
style:
TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
Text(
// tx.date.toString(),
// DateFormat().format(tx.date),
// DateFormat('yyyy-MM-dd').format(tx.date),
// DateFormat('yyyy/MM/dd').format(tx.date),
DateFormat.yMMMd().format(tx.date),
style: TextStyle(
color: Colors.grey,
),
)
],
)
],
),
);
}).toList(),
),
);
}
}
使用 ListView.builder()
需要提供两个参数,itemBuilder
函数,以及 列表长度 itemCount
,上面的代码修改得到如下代码:
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../models/transaction.dart';
class TransactionList extends StatelessWidget {
final List<Transaction> transactions;
TransactionList(this.transactions);
@override
Widget build(BuildContext context) {
return Container(
height: 300,
child: ListView.builder(
itemBuilder: ((ctx, index) {
return Card(
child: Row(
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(
vertical: 10,
horizontal: 10,
),
decoration: BoxDecoration(
border: Border.all(
color: Colors.purple,
width: 2,
),
),
padding: EdgeInsets.all(10),
child: Text('\$${transactions[index].amount}',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.purple,
)),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
transactions[index].title,
style:
TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
Text(
DateFormat.yMMMd().format(transactions[index].date),
style: TextStyle(
color: Colors.grey,
),
)
],
)
],
),
);
}),
itemCount: transactions.length,
),
);
}
}