布局
基本布局
- Row(水平布局):在水平(X轴)方向上排列子widget的列表。
- Column(垂直布局):在垂直(Y轴)方向上排列子widget的列表。
- Stack(可重叠布局):可以允许其子widget简单的堆叠(Z轴)在一起。
- IndexedStack(单一显示可重叠布局):相比Stack后面编码的widget显示在Z轴上方,IndexedStack通过index可以控制显示哪个widget显示在Z轴的上方,注意,只显示一个。
- ListView(滚动列表):最常用的滚动widget。
Row
代码
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text('1'),
new Text('2'),
new Text('3'),
],
)
常用参数
mainAxisAlignment
- X轴方向上的对齐方式
- spaceBetween:沿X轴方向均分,子widget之间的空白区域相等,两侧贴边,比如只有两个子widget就在两边,三个就左中右这样。
- spaceAround:沿X轴方向均分,左右两侧不贴边,有空白区域,但空白区域是子widget之间的空白区域的1/2。
- spaceEvenly:沿X轴方向均分,左右两侧不贴边,有空白区域,空白区域和子widget之间的空白区域大小一致。
crossAxisAlignment
textBaseline
- 文本内容的基线类型,就是文本的水平边界线,注意,只有水平
- alphabetic:以字母字符底部的水平线对齐(不论中英文,都是用文字的最底部对齐)
- ideographic:以表意字符的水平线对齐。(英文如pgj这些底部会比中文矮一些)
mainAxisSize
verticalDirection
- 垂直方向上的排列顺序
- up:子widget从bottom开始往top排列;
- down:子widget从top开始往bottom排列。
- 搭配crossAxisAlignment的start和end属性有如下不同:
textDirection
- 与verticalDirection类似,水平方向上的排列顺序
- ltr:left to right,从左到右排列;
- rtl:rigth to left,从右到左排列;
- 同verticalDirection类似,搭配mainAxisAlignment使用,如下:
Column
代码
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text('1'),
new Text('2'),
new Text('3'),
],
)
常用参数
mainAxisAlignment
- Y轴方向上的对齐方式
- spaceBetween:沿Y轴方向均分,子widget之间的空白区域相等,比如只有两个子widget就在上下,三个就上中下这样。
- spaceAround:沿Y轴方向均分,上下两侧不贴边,有空白区域,但空白区域是子widget之间的空白区域的1/2。
crossAxisAlignment
mainAxisSize
verticalDirection
- 垂直方向上的排列顺序
- up:子widget从bottom开始往top排列;
- down:子widget从top开始往bottom排列。
- 搭配mainAxisAlignment的start和end属性有如下不同:
textDirection
- 与verticalDirection类似,水平方向上的排列顺序
- ltr:left to right,从左到右排列;
- rtl:rigth to left,从右到左排列;
- 同verticalDirection类似,搭配crossAxisAlignment使用,如下:
Stack
代码
Stack(
alignment: Alignment(-1.0,0.0),//等价于Alignment.centerLeft
children: <Widget>[
Positioned(child: Container(width: 100.0,height: 100.0,color: Colors.red,),),
Positioned(child: Container(width: 90.0,height: 90.0,color: Colors.green,),),
Positioned(child: Container(width: 80.0,height: 80.0,color: Colors.blue,),),
new Text('-1,0ncenterLeft',textAlign: TextAlign.left,),
],
)
完整示例
Container(
width: 200,
height: 200,
child: Stack(
children: <Widget>[
Positioned(
// 若是不指定位置就是(0,0)
// 若是不指定size就是子view的size
// top: 50.0,
// left: 50.0,
child: Container(
width: 200,
height: 200,
),
),
Positioned(
top: 0.0,
left: 190.0,
child: Container(
width: 10.0,
height: 10.0,
color: Colors.green,
),
),
],
),
);
常用参数
alignment
textDirection
fit
overflow
IndexedStack
代码
IndexedStack(
sizing: StackFit.expand,
index: 1,
children: <Widget>[
Positioned(child: Container(width: 100.0,height: 100.0,color: Colors.red,),),
Positioned(child: Container(width: 130.0,height: 90.0,color: Colors.green,),),
Positioned(child: Container(width: 80.0,height: 120.0,color: Colors.blue,),),
],
),
index就是children的length的区间之中的值。
比如上面的代码,就只显示index为1的子widget,也就是第二个。
常用参数
ListView
代码
/// 默认构造
ListView(
children: [
new Text('1'),
Divider(),
new Text('2'),
Divider(),
new Text('3'),
Divider(),
],
),
/// ListView.builder()构造
final List<String> name = <String>['1','2','3',];
ListView.builder(
itemCount: name.length,
itemBuilder: (context, index) {
return Text(name[index]);
},
),
/// ListView.separated()构造
ListView.separated(
itemBuilder: (context, index) {
return Text(name[index]);
},
separatorBuilder: (context, index) {
return Divider();//分割线
},
itemCount: name.length,
),
/// ListView.custom()
ListView.custom(
childrenDelegate: SliverChildBuilderDelegate(
(context, index) {
return Text(name[index]);
},
childCount: name.length,
),
),
详细代码
var lv1 = ListView(
//主轴滚动方向:垂直vertical,竖直horizontal ,默认为垂直vertical,
scrollDirection: Axis.vertical,
//是否反向 默认为false,正常顺序从起始点开始正序,true为从末尾开始排列
reverse: false,
//滚动控制器,默认为null
controller:null,
//是否强制滚动(顶部或底部时是否可以滚动),默认是false,如果为true,Controller必须为null
primary: false,
//视图如何响应用户的手势滑动,有内置实现强制可以滚动 const AlwaysScrollableScrollPhysics();和强制不可以滚动const ScrollPhysics(),可忽略primary属性
physics: const AlwaysScrollableScrollPhysics(),
//默认为false,滚动视图在[滚动方向]中的范围是否应由正在查看的内容决定。
shrinkWrap: true,
//item的padding值
padding: const EdgeInsets.all(10.0),
//item交叉轴方向的大小,默认自适应,vertical时为高度,horizontal时为高度
itemExtent: 50.0,
//是否自动保存滑出屏幕外的字widget的状态,保证widget不被回收,可复用,false的手动保存。默认为true
addAutomaticKeepAlives: true,
//是否放置到重绘列表中,复杂widget可提高性能,默认为true
addRepaintBoundaries: true,
//缓存区大小,默认为250
cacheExtent: 250.0,
//默认构造函数中特有,直接将子widget放置内,一次性渲染完成,适合少量数据
children: [
new Text('测试1'),
Divider(),
new Text('测试2'),
Divider(),
new Text('测试3'),
Divider(),
new Text('测试4'),
Divider(),
new Text('测试5'),
Divider(),
],
);
每个item不同的listview
import 'package:flutter/material.dart';
class MyListPage extends StatelessWidget {
final List<Item> itemList = [
Item(type: ItemType.button, data: ['Button 1', 'Button 2']),
Item(type: ItemType.text, data: 'Hello World'),
Item(
type: ItemType.image,
data: 'https://example.com/images/image.jpg'),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My List Page'),
),
body: ListView.builder(
itemCount: itemList.length,
itemBuilder: (BuildContext context, int index) {
Item item = itemList[index];
Widget itemWidget;
// 根据item类型构建不同的widget
switch (item.type) {
case ItemType.button:
List<String> buttonTexts = item.data;
itemWidget = Row(
children: [
ElevatedButton(
onPressed: () {},
child: Text(buttonTexts[0]),
),
ElevatedButton(
onPressed: () {},
child: Text(buttonTexts[1]),
),
],
);
break;
case ItemType.text:
String textData = item.data;
itemWidget = Text(textData);
break;
case ItemType.image:
String imageUrl = item.data;
itemWidget = Image.network(imageUrl);
break;
}
return ListTile(
title: itemWidget,
);
},
),
);
}
}
class Item {
final ItemType type;
final dynamic data;
Item({
required this.type,
required this.data,
});
}
enum ItemType {
button,
text,
image,
}
垂直滑动里嵌套水平滑动
class _PageBizCertificateState extends eState<PageBizCertificate> {
final List<String> items = List.generate(20, (index) => 'Item $index');
@override
Widget pageBody(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return MyListItem(title: items[index]);
},
);
}
Widget MyListItem({required String title}) {
return Container(
padding: EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('第一行文本'),
SizedBox(height: 8.0),
MyHorizontalScrollList(),
SizedBox(height: 8.0),
Text('第三行文本'),
],
),
);
}
Widget MyHorizontalScrollList() {
return Container(
height: 100.0,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 10,
itemBuilder: (context, index) {
return Container(
width: 100.0,
margin: EdgeInsets.all(4.0),
color: Colors.blue,
child: Center(
child: Text('水平项 $index'),
),
);
},
),
);
}
}
参数列表
- scrollDirection:主轴滚动方向;默认垂直滚动Axis.vertical,还可水平滚动Axis.horizontal
- reverse:是否反向排列,默认false,即正序排列
- controller:滚动控制器,默认为null
- primary:是否强制滚动,默认false
- physics:响应用户滑动。
- shrinkWrap:滚动视图在滚动方向中的范围是否应由正在查看的内容决定。默认为false
- padding:距边框item边间距
- cacheExtent:缓存大小,默认250.0
- itemExtent:item在交叉轴方向上的长度;null时为自适应
- addAutomaticKeepAlives:是否自动保存滑出屏幕外的字widget的状态,默认true,保存,可复用
- addRepaintBoundaries:是否放置到重绘列表中;默认true,可提高性能
- itemBuilder:builder和separated构造函数特有要传入参数,定义item的样式
- separatorBuilder:separated构造函数特有要传入的参数,定义分割线的样式
- itemCount:列表可滚动的item数量,默认构造没有
- childrenDelegate:内部都是靠此类实现滚动和布局,但只有custom构造函数需要传入,其余都内部实现
原文地址:https://blog.csdn.net/sadkhkuhkjasga/article/details/134647520
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_39590.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。