组件1:MaterialApp、Container、Text、Image、Icon
组件2:ListView、GridView
组件3:Padding、Row 、Column、Stack、Align、Positioned
组件4:AspectRatio、Row 、Button
组件5:Wrap、StatelessWidget 、StatefulWidget、Dialog、PageView、TextField
3.6 ListView
名称 | 功能 |
---|---|
scrollDirection | Axis.horizontal 横向,Axis.vertical 纵向 |
reverse | 反向,元素从下面开始,往上排 |
children | 子元素 |
ListView 纵向的时候,内部的Container的宽度设置不生效
ListView 横向的时候,内部的Container的高度设置不生效
3.6.1 ListTitle
ListTile 是Flutter 给我们准备好的widget 提供非常常见的构造和定义方式,包括文字,icon,点击事件,一般是能够满足基本需求,但是就不能自己定义了
this.leading, // item 前置图标
this.title, // item 标题
this.subtitle, // item 副标题
this.trailing, // item 后置图标
this.isThreeLine = false, // item 是否三行显示
this.dense, // item 直观感受是整体大小
this.contentPadding, // item 内容内边距
this.enabled = true
this.onTap, // item onTap 点击事件
this.onLongPress, // item onLongPress 长按事件
this.selected = false, // item 是否选中状态
代码如下:
class MyList extends StatelessWidget {
const MyList({super.key});
@override
Widget build(BuildContext context) {
return ListView(
children: const <Widget>[
ListTile(
leading: Icon(Icons.home),
title: Text("我是列表"),
),
Divider(),
ListTile(
subtitle: Text("我是副标题"),
title: Text("我是列表"),
),
Divider(),
ListTile(
trailing: Icon(Icons.person),
title: Text("我是列表"),
),
Divider(),
],
);
}
}
3.6.2 动态列表
class MyList extends StatelessWidget {
const MyList({super.key});
List<Widget> _listData() {
List<Widget> list = [];
for (var i = 0; i < 20; i++) {
list.add(ListTile(
title: Text("data $i"),
));
}
return list;
}
@override
Widget build(BuildContext context) {
return ListView(
children: _listData(),
);
}
}
也可以把数据单独放一个文件中 data.dart
List dtListData = [
{"name": "zhangsan", "age": 19},
{"name": "李四", "age": 20},
{"name": "找份", "age": 18},
{"name": "没事", "age": 31},
{"name": "四五年", "age": 12},
{"name": "奥", "age": 3},
{"name": "没事", "age": 9},
{"name": "饿哦", "age": 19},
];
引入文件
import 'res/data.dart';
class MyList extends StatelessWidget {
const MyList({super.key});
List<Widget> _listData() {
// 第一种写法
List<Widget> list = [];
for (var i = 0; i < dtListData.length; i++) {
var data = dtListData[i];
String name = data["name"];
int age = data["age"];
list.add(ListTile(
title: Text("姓名 $name"),
subtitle: Text("年龄 $age"),
));
}
return list;
// 第二种写法
var list = dtListData.map((e) {
String name = e["name"];
int age = e["age"];
return ListTile(
title: Text("姓名 $name"),
subtitle: Text("年龄 $age"),
);
});
return list.toList();
}
@override
Widget build(BuildContext context) {
return ListView(
children: _listData(),
);
}
}
2.6.3 builder
builder 顾名思义 构造 可以非常方便的构建我们自己定义的child布局,所以在Flutter中非常的常用
//设置滑动方向 Axis.horizontal 水平 默认 Axis.vertical 垂直
scrollDirection: Axis.vertical,
//内间距
padding: EdgeInsets.all(10.0),
//是否倒序显示 默认正序 false 倒序true
reverse: false,
//false,如果内容不足,则用户无法滚动 而如果[primary]为true,它们总是可以尝试滚动。
primary: true,
//确定每一个item的高度 会让item加载更加高效
itemExtent: 50.0,
//内容适配
shrinkWrap: true,
//item 数量
itemCount: list.length,
//滑动类型设置
physics: new ClampingScrollPhysics(),
//cacheExtent 设置预加载的区域
cacheExtent: 30.0,
//滑动监听
//controller ,
使用builder时,itemCount 和 itemBuilder 必须有
class MyBuildList extends StatelessWidget {
List<String> list = [];
// ignore: empty_constructor_bodies
MyBuildList({Key? key}) : super(key: key) {
for (var i = 0; i < 20; i++) {
list.add("value $i");
}
}
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: list.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(list[index]),
);
});
}
}
3.7 GridView
可以通过 GridView.count 实现网格布局,控制一行有多少个子组件
可以通过 GridView.extent 实现网格布局,控制一行每个组件的长度,长度超出一行,就放下一行。
名称 | 功能 |
---|---|
scrollDirection | 滚动方向,Axis.horizontal 横向,Axis.vertical 纵向 |
reverse | 组件反向排序,元素从下面开始,往上排 |
children | 子元素 |
padding | 内边距 |
crossAxisSpacing | 子组件之间水平距离 |
mainAxisSpacing | 子组件之间垂直距离 |
crossAxisCount | 用在 GridView.count 中,一行中子组件数量 |
maxCrossAxisExtent | 用在 GridView.extent 中,每个子组件的固定的最大长度 |
childAspectRatio | 设置宽高比例 |
3.7.1 GridView.count 和 GridView.extent
// GridView.count 实现网格布局
class MyGridViewCount extends StatelessWidget {
const MyGridViewCount({super.key});
@override
Widget build(BuildContext context) {
return GridView.count(
// 一行有多少个元素
crossAxisCount: 3,
children: const [
Icon(Icons.home),
Icon(Icons.home_max),
Icon(Icons.shop),
Icon(Icons.percent),
Icon(Icons.person),
Icon(Icons.adb_outlined),
Icon(Icons.assessment),
Icon(Icons.deblur),
Icon(Icons.sick),
],
);
}
}
// GridView.extent 实现网格布局
class MyGridViewExtent extends StatelessWidget {
const MyGridViewExtent({super.key});
@override
Widget build(BuildContext context) {
return GridView.extent(
// 每个元素的长度是固定的40
maxCrossAxisExtent: 100,
children: const [
Icon(Icons.home),
Icon(Icons.home_max),
Icon(Icons.shop),
Icon(Icons.percent),
Icon(Icons.person),
Icon(Icons.adb_outlined),
Icon(Icons.assessment),
Icon(Icons.deblur),
Icon(Icons.sick),
],
);
}
}
3.7.2 GridView.builder
class MyGridViewBuilder extends StatelessWidget {
const MyGridViewBuilder({super.key});
Widget _initWidget(context, index) {
return Container(
decoration: BoxDecoration(border: Border.all(color: Colors.redAccent)),
child: Text("$index"),
);
}
@override
Widget build(BuildContext context) {
return GridView.builder(
itemCount: 10, // 循环次数
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3, // 一行显示多少个元素
crossAxisSpacing: 10, // 子组件 水平间距
mainAxisSpacing: 10, // 子组件 垂直间距
childAspectRatio: 1), // 宽高比
itemBuilder: _initWidget
// (content, index) {}
);
}
}
注:
使用 SliverGridDelegateWithFixedCrossAxisCount ,使用属性 crossAxisCount
使用 SliverGridDelegateWithMaxCrossAxisExtent , 使用属性 maxCrossAxisExtent
网友评论