GridView
1. GridView 使用构造函数创建(GridView+SliverGridDelegateWithFixedCrossAxisCount)
/* GridView(SliverGridDelegateWithFixedCrossAxisCount)
> 展示多列数据
GridView 一 使用构造函数来创建, 它比ListView多了一个参数GridDelegate
GridDelegate 用于控制交叉轴的item数量或者宽度,需要传入的类型是SliverGridDelegate,
但是它是一个抽象类,需要使用它的子类: SliverGriddelegateWithFixedCrossAxisCount
SliverGridDelegateWithFixedCrossAxisCount
最大的列数Count
*/
class Content1 extends StatelessWidget {
List<Widget> getGridWidgets() {
return List.generate(100, (index) {
return Container(
color: Colors.purple,
alignment: Alignment(0, 0),
child: Text(
'item$index',
style: TextStyle(fontSize: 20, color: Colors.white),
),
);
});
}
@override
Widget build(BuildContext context) {
return GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 1.0,
// mainAxisExtent: 200,
),
children: getGridWidgets(),
);
}
}
2. GridView(SliverGridDelegateWithMaxCrossAxisExtent)
/* GridView(SliverGridDelegateWithMaxCrossAxisExtent)
最大的宽度100
*/
class Content2 extends StatelessWidget {
List<Widget> getGridWidgets() {
return List.generate(100, (index) {
return Container(
color: Colors.blue,
child: Text(
'item$index',
style: TextStyle(fontSize: 20, color: Colors.black),
),
);
});
}
@override
Widget build(BuildContext context) {
return GridView(
scrollDirection: Axis.vertical,
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 100,
mainAxisSpacing: 20, // 方向即时主轴。垂直方向主轴就是上下间距,水平方向主轴就是左右间距。 默认方向就是垂直方向
crossAxisSpacing: 10, //
childAspectRatio: 1.0),
children: getGridWidgets(),
);
}
}
3. GridView.count()
/* GridView.count()
等价于 == GridView(SliverGridDelegateWithFixedCrossAxisCount)
count显示几列
mainAxisSpacing: 主轴间距
crossAxisSpacing: 交叉轴间距
childAspectRatio: item的宽度高度比例
*/
4. GridView.extent(maxCrossAxisExtent: 最大的宽度)
/* GridView.extent(maxCrossAxisExtent: 最大的宽度)
等价于GridView(SliverGridDelegateWithMaxCrossAxisExtent)
*/
class Content4 extends StatelessWidget {
List<Widget> getGridWidgets() {
return List.generate(31, (index) {
return Container(
color: Colors.deepOrange,
alignment: Alignment(0, 0),
child: Text('item$index'),
);
});
}
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(0), // 如果这个设置10, 就会导致外层滚动边界有10,可以去掉!
child: GridView.extent(
padding: EdgeInsets.all(10), // 设置这个间距10,滚动还是全屏
maxCrossAxisExtent: 200,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 1.0,
children: getGridWidgets(),
),
);
}
}
5. GridView.build
- 提高性能,跟ListView.build 一样,滚动到出现时渲染视图
class Content5 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GridView.builder(
padding: EdgeInsets.all(10),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4, // 列数
mainAxisSpacing: 10, // 主轴的间距
crossAxisSpacing: 10, // 交叉轴的间距
childAspectRatio: 1.0, // item宽度/高度的比例
),
itemBuilder: (BuildContext context, int index) {
return Container(
padding: EdgeInsets.all(10), // 边距10
color: Colors.tealAccent,
alignment: Alignment(0, 0),
child: Text('item$index'),
);
},
itemCount: 41, // 整个item数量
shrinkWrap: false, // 设置为true就会上拉不动、只能下拉.
//physics: ClampingScrollPhysics(), // 设置以后,上下都不能拉
);
}
}
6. GridView.build 加载真实JSON数据
import 'dart:convert';
import 'package:flutter/services.dart' show rootBundle;
class MovieModel {
String title = '';
String description = '';
String img = '';
MovieModel(this.title, this.description, this.img);
// https://dart.dev/tools/diagnostic-messages#not_initialized_non_nullable_instance_field
MovieModel.withMap(Map<String, dynamic> map) {
this.title = map['title'];
this.description = map['description'];
this.img = map['img'];
}
}
Future<List<MovieModel>> getMovies() async {
String jsonString = await rootBundle.loadString('assets/flutter.json');
final result = json.decode(jsonString);
List<MovieModel> movies = [];
for (Map<String, dynamic> map in result) {
movies.add(MovieModel.withMap(map));
}
return movies;
}
class _Content6State extends State<Content6> {
List<MovieModel> movies = [];
@override
void initState() {
// TODO: implement initState
super.initState();
getMovies().then((value) {
setState(() {
this.movies = value;
});
});
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.cyan,
child: GridView.builder(
padding: EdgeInsets.all(10),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 1.0),
itemBuilder: (BuildContext context, int index) {
return Container(
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 图片
Image.network(
movies[index].img,
fit: BoxFit.fitHeight, // fitHeight
height: 110, // 280
),
// 间距10
SizedBox(height: 8),
// title
Text(
movies[index].title,
style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
SizedBox(height: 3),
Text(
movies[index].description,
style: TextStyle(fontSize: 13),
),
// description
],
),
);
},
itemCount: movies.length,
),
);
}
}