小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
之前写到一个App内显示升级弹框需求,大体样式如下:
其中,升级说明的条数不固定,可多可少,所以这里要满足的要求有:弹框高度要根据升级条目的多少自适应,但是为了美观最高不能超过600,当条目很多时需要可以滚动。 为了要满足要求肯定要使用Listview + Flexible + Container的maxHeight属性进行布局。一开始的代码是这样的:
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 30),
constraints: BoxConstraints(
maxHeight: 700
),
color: Colors.white,
width: 500,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: const EdgeInsets.all(20),
child: Text("新版本来啦~",style: TextStyle(
color: Colors.black,
fontSize: 50,)),
),
listItems(),
Container(
padding: const EdgeInsets.all(20),
child: Text("立即升级",style: TextStyle(
color: Colors.red,
fontSize: 30,)),
),
],
),
);
}
Widget listItems() {
List<Widget> updateList = [];
list.forEach((item) {
updateList.add(Text(
'$item',
style: TextStyle(
color: Colors.black,
fontSize: 30,),
));
});
return Flexible(
child: ListView(
children: updateList,
),
);
}
maxHeight,ListView,Flexible全都有了,但是运行起来就发现了问题:当升级文案条目很少的时候高度依然也会达到maxHeight设置的最大值600.想想一定是因为listview自动将高度撑大到了他所能到的父布局的最大高度。那么从这个方向入手终于在网上找到了答案,那便是设置listview的shrinkWrap为true即可。
ListView(
shrinkWrap: true,
children: updateList,
)
Flutter中给出这个属性的解释是:**该属性将决定列表的长度是否仅包裹其内容的长度,**默认值为false,也就是说默认情况是自动将listview高度延伸到最大,基本上所有的滚动组件都有这个属性。 其实之前是用到过这个属性的,当时也没有深入研究其含义。趁此机会可以再复习一下ListView组件中属性的介绍:
ListView({
Axis scrollDirection = Axis.vertical,
ScrollController controller,
ScrollPhysics physics,
bool shrinkWrap = false,
EdgeInsetsGeometry padding,
this.itemExtent,
double cacheExtent,
List<Widget> children = const <Widget>[],
})
- scrollDirection: 列表的滚动方向,可选值有Axis的horizontal和vertical,可以看到默认是垂直方向上滚动;
- controller : 控制器,与列表滚动相关,比如监听列表的滚动事件;
- physics: 列表滚动至边缘后继续拖动的物理效果,Android与iOS效果不同。Android会呈现出一个波纹状(对应ClampingScrollPhysics),而iOS上有一个回弹的弹性效果(对应BouncingScrollPhysics)。如果你想不同的平台上呈现各自的效果可以使用AlwaysScrollableScrollPhysics,它会根据不同平台自动选用各自的物理效果。如果你想禁用在边缘的拖动效果,那可以使用NeverScrollableScrollPhysics;
- shrinkWrap: 该属性将决定列表的长度是否仅包裹其内容的长度。当ListView嵌在一个无限长的容器组件中时,shrinkWrap必须为true,否则Flutter会给出警告;
- padding: 列表内边距;
- itemExtent: 子元素长度。当列表中的每一项长度是固定的情况下可以指定该值,有助于提高列表的性能(因为它可以帮助ListView在未实际渲染子元素之前就计算出每一项元素的位置);
- cacheExtent: 预渲染区域长度,ListView会在其可视区域的两边留一个-cacheExtent长度的区域作为预渲染区域(对于ListView.build或ListView.separated构造函数创建的列表,不在可视区域和预渲染区域内的子元素不会被创建或会被销毁);
- children: 容纳子元素的组件数组。 代码地址