[英]How to create GridView Layout in Flutter
I am trying to layout a 4x4 grid of tiles in flutter.我正在尝试在颤动中布局一个 4x4 的瓷砖网格。 I managed to do it with columns and rows.
我设法用列和行来做到这一点。 But now I found the
GridView
component.但现在我找到了
GridView
组件。 Could anyone provide an example on how to do it using it?任何人都可以提供一个如何使用它的例子吗?
I can't really wrap my head around the docs.我无法真正理解文档。 I don't seem to get the results I want.
我似乎没有得到我想要的结果。
Use whichever suits your need.使用适合您需要的任何一种。
GridView.count(...)
GridView.count( crossAxisCount: 2, children: <Widget>[ FlutterLogo(), FlutterLogo(), FlutterLogo(), FlutterLogo(), ], )
GridView.builder(...)
GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2), itemBuilder: (_, index) => FlutterLogo(), itemCount: 4, )
GridView(...)
GridView( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2), children: <Widget>[ FlutterLogo(), FlutterLogo(), FlutterLogo(), FlutterLogo(), ], )
GridView.custom(...)
GridView.custom( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2), childrenDelegate: SliverChildListDelegate( [ FlutterLogo(), FlutterLogo(), FlutterLogo(), FlutterLogo(), ], ), )
GridView.extent(...)
GridView.extent( maxCrossAxisExtent: 400, children: <Widget>[ FlutterLogo(), FlutterLogo(), FlutterLogo(), FlutterLogo(), ], )
Output (same for all):输出(全部相同):
A simple example loading images into the tiles.将图像加载到图块中的简单示例。
import 'package:flutter/material.dart';
void main() {
runApp( MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white30,
child: GridView.count(
crossAxisCount: 4,
childAspectRatio: 1.0,
padding: const EdgeInsets.all(4.0),
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
children: <String>[
'http://www.for-example.org/img/main/forexamplelogo.png',
'http://www.for-example.org/img/main/forexamplelogo.png',
'http://www.for-example.org/img/main/forexamplelogo.png',
'http://www.for-example.org/img/main/forexamplelogo.png',
'http://www.for-example.org/img/main/forexamplelogo.png',
'http://www.for-example.org/img/main/forexamplelogo.png',
'http://www.for-example.org/img/main/forexamplelogo.png',
'http://www.for-example.org/img/main/forexamplelogo.png',
'http://www.for-example.org/img/main/forexamplelogo.png',
'http://www.for-example.org/img/main/forexamplelogo.png',
'http://www.for-example.org/img/main/forexamplelogo.png',
].map((String url) {
return GridTile(
child: Image.network(url, fit: BoxFit.cover));
}).toList()),
);
}
}
The Flutter Gallery app contains a real world example, which can be found here . Flutter Gallery 应用程序包含一个真实世界的示例,可在此处找到。
GridView
is used for implementing material grid lists . GridView
用于实现材质网格列表。 If you know you have a fixed number of items and it's not very many (16 is fine), you can use GridView.count
.如果您知道您有固定数量的项目并且不是很多(16 个就可以),您可以使用
GridView.count
。 However, you should note that a GridView
is scrollable, and if that isn't what you want, you may be better off with just rows and columns.但是,您应该注意
GridView
是可滚动的,如果这不是您想要的,那么您最好只使用行和列。
import 'dart:collection';
import 'package:flutter/scheduler.dart';
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/foundation.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.orange,
),
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget{
@override
Widget build(BuildContext context){
return new Scaffold(
appBar: new AppBar(
title: new Text('Grid Demo'),
),
body: new GridView.count(
crossAxisCount: 4,
children: new List<Widget>.generate(16, (index) {
return new GridTile(
child: new Card(
color: Colors.blue.shade200,
child: new Center(
child: new Text('tile $index'),
)
),
);
}),
),
);
}
}
Please visit this repo .请访问这个repo 。
Widget _gridView() {
return GridView.count(
crossAxisCount: 4,
padding: EdgeInsets.all(4.0),
childAspectRatio: 8.0 / 9.0,
children: itemList
.map(
(Item) => ItemList(item: Item),
)
.toList(),
);
}
Below screenshot contains crossAxisCount: 2下面的屏幕截图包含crossAxisCount: 2
There are few named constructors in GridView
for different scenarios, GridView
针对不同场景的命名构造函数很少,
Constructors构造函数
GridView
GridView.builder
GridView.count
GridView.custom
GridView.extent
Below is a example of GridView
constructor:下面是
GridView
构造函数的示例:
import 'package:flutter/material.dart';
void main() => runApp(
MaterialApp(
home: ExampleGrid(),
),
);
class ExampleGrid extends StatelessWidget {
List<String> images = [
"https://uae.microless.com/cdn/no_image.jpg",
"https://images-na.ssl-images-amazon.com/images/I/81aF3Ob-2KL._UX679_.jpg",
"https://www.boostmobile.com/content/dam/boostmobile/en/products/phones/apple/iphone-7/silver/device-front.png.transform/pdpCarousel/image.jpg",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSgUgs8_kmuhScsx-J01d8fA1mhlCR5-1jyvMYxqCB8h3LCqcgl9Q",
"https://ae01.alicdn.com/kf/HTB11tA5aiAKL1JjSZFoq6ygCFXaw/Unlocked-Samsung-GALAXY-S2-I9100-Mobile-Phone-Android-Wi-Fi-GPS-8-0MP-camera-Core-4.jpg_640x640.jpg",
"https://media.ed.edmunds-media.com/gmc/sierra-3500hd/2018/td/2018_gmc_sierra-3500hd_f34_td_411183_1600.jpg",
"https://hips.hearstapps.com/amv-prod-cad-assets.s3.amazonaws.com/images/16q1/665019/2016-chevrolet-silverado-2500hd-high-country-diesel-test-review-car-and-driver-photo-665520-s-original.jpg",
"https://www.galeanasvandykedodge.net/assets/stock/ColorMatched_01/White/640/cc_2018DOV170002_01_640/cc_2018DOV170002_01_640_PSC.jpg",
"https://media.onthemarket.com/properties/6191869/797156548/composite.jpg",
"https://media.onthemarket.com/properties/6191840/797152761/composite.jpg",
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: GridView(
physics: BouncingScrollPhysics(), // if you want IOS bouncing effect, otherwise remove this line
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),//change the number as you want
children: images.map((url) {
return Card(child: Image.network(url));
}).toList(),
),
);
}
}
If you want your GridView items to be dynamic according to the content, you can few lines to do that but the simplest way to use StaggeredGridView
package.如果你希望你的 GridView 项目根据内容是动态的,你可以用几行来做到这一点,但最简单的方法是使用
StaggeredGridView
包。 I have provided an answer with example here .我在这里提供了一个例子的答案。
Below is an example for a GridView.count
:以下是
GridView.count
的示例:
import 'package:flutter/material.dart';
void main() => runApp(
MaterialApp(
home: ExampleGrid(),
),
);
class ExampleGrid extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: GridView.count(
crossAxisCount: 4,
children: List.generate(40, (index) {
return Card(
child: Image.network("https://robohash.org/$index"),
); //robohash.org api provide you different images for any number you are giving
}),
),
);
}
}
Screenshot for above snippet:上述代码段的屏幕截图:
Example for a SliverGridView
: SliverGridView
:
import 'package:flutter/material.dart';
void main() => runApp(
MaterialApp(
home: ExampleGrid(),
),
);
class ExampleGrid extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
primary: false,
slivers: <Widget>[
SliverPadding(
padding: const EdgeInsets.all(20.0),
sliver: SliverGrid.count(
crossAxisSpacing: 10.0,
crossAxisCount: 2,
children: List.generate(20, (index) {
return Card(child: Image.network("https://robohash.org/$index"));
}),
),
),
],
)
);
}
}
You can use a flutter_layout_grid package您可以使用flutter_layout_grid包
First of all, we need to add it to our pubspec.yaml
:首先,我们需要将它添加到
our pubspec.yaml
:
dependencies:
flutter_layout_grid: ^1.0.3
Then, we can define a custom ItemCardLayoutGrid
widget to show each ItemCard
inside a LayoutGrid
widget:然后,我们可以定义一个自定义
ItemCardLayoutGrid
小部件以在LayoutGrid
小部件中显示每个ItemCard
:
import 'package:flutter_layout_grid/flutter_layout_grid.dart';
class ItemCardLayoutGrid extends StatelessWidget {
const ItemCardLayoutGrid({
Key? key,
required this.crossAxisCount,
required this.items,
})
// we only plan to use this with 1 or 2 columns
: assert(crossAxisCount == 1 || crossAxisCount == 2),
// assume we pass an list of 4 items for simplicity
assert(items.length == 4),
super(key: key);
final int crossAxisCount;
final List<ItemCardData> items;
@override
Widget build(BuildContext context) {
return LayoutGrid(
// set some flexible track sizes based on the crossAxisCount
columnSizes: crossAxisCount == 2 ? [1.fr, 1.fr] : [1.fr],
// set all the row sizes to auto (self-sizing height)
rowSizes: crossAxisCount == 2
? const [auto, auto]
: const [auto, auto, auto, auto],
rowGap: 40, // equivalent to mainAxisSpacing
columnGap: 24, // equivalent to crossAxisSpacing
// note: there's no childAspectRatio
children: [
// render all the cards with *automatic child placement*
for (var i = 0; i < items.length; i++)
ItemCard(data: items[i]),
],
);
}
}
And pass a list of children inside a loop (our ItemCard
widgets):并在循环中传递一个子项列表(我们的
ItemCard
小部件):
children: [
// render all the cards with *automatic child placement*
for (var i = 0; i < items.length; i++)
ItemCard(data: items[i]),
]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.