Vip*_*sri 14 gridview dart staggered-gridview flutter
如何在扑动中实现这个复杂的视图?
我正在尝试GridView使用n列实现,并且子应该具有一定的宽高比(比如说1.3),但是孩子的高度应该是(在Android术语中包装内容).
我被困了,因为我理解GridView childAspectRatio:1.3(默认值:1)总是以相同的宽高比而不是动态内容来布置孩子.
注意:孩子应根据图像的高度扩展其高度
使用案例:我正在尝试实现如下所示的视图,其中图像被包裹,height = wrap content以便在具有拉伸高度的图像看起来很好并且形成StaggeredGridView类似结构的情况下.

Rom*_*tel 14
编辑:我StaggeredTile.fit在0.2.0中添加了构造函数.有了它你应该能够建立你的应用程序;-).
第一条评论:
现在使用StaggeredGridView,布局和子渲染完全独立.所以@rmtmckenzie说,你必须得到图像大小来创建你的瓷砖.然后你可以使用StaggeredTile.count构造函数的双值mainAxisCellCount参数:new StaggeredTile.count(x, x*h/w)(这里h是你的形象和高度w.它的宽度,以便与瓷砖具有相同的高宽比为你的形象.
您想要完成的工作需要更多的工作,因为您希望在图像下方有一些区域并提供一些信息.为此我认为你必须在创建它之前计算它的实际宽度并使用StaggeredTile.extent构造函数.
我知道这并不理想,我正在开发一种创建布局的新方法.我希望它有助于构建像你这样的场景.
Bla*_*nka 12
首先让我告诉你我是如何走到这里的:
在我的应用程序中,我想要一个网格视图来显示我的广告卡,所有来自服务器数据库的数据和图像都来自服务器,并且图像的大小不同。我曾经FutureBuilder将这些数据映射到GridView. 首先我尝试使用:
double cardWidth = MediaQuery.of(context).size.width / 3.3;
double cardHeight = MediaQuery.of(context).size.height / 3.6;
//....
GridView.count(
childAspectRatio: cardWidth / cardHeight,
//..
Run Code Online (Sandbox Code Playgroud)
如您所见,它不会对所有卡片都具有动态性。我像你一样来到这里,并试图使用所有很棒的答案,你必须解决一些问题才能理解如何,但这些答案中的任何一个都完全解决了我的问题。
使用@RomainRastel回答并感谢他的StaggeredGridView包裹。我必须使用StaggeredGridView.count我的构造函数来映射所有卡片,而对于staggeredTiles属性,我必须再次映射所有卡片并为每个StaggeredTile.fit(2).
我相信你还没有明白,所以让我们尝试一个简单的例子,这样你就不需要去其他地方找到答案:
首先添加依赖pubspec.yaml,现在版本是0.2.5. 您可以在此处查看最新版本。
dependencies:
flutter_staggered_grid_view: ^0.2.5
Run Code Online (Sandbox Code Playgroud)
如果您要从 Internet 获取数据或者要复制粘贴此示例,则还必须添加此依赖项:http: ^0.12.0.
import 'package:flutter/material.dart';
//this is what you need to have for flexible grid
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
//below two imports for fetching data from somewhere on the internet
import 'dart:convert';
import 'package:http/http.dart' as http;
//boilerplate that you use everywhere
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Flexible GridView",
home: HomePage(),
);
}
}
//here is the flexible grid in FutureBuilder that map each and every item and add to a gridview with ad card
class HomePage extends StatelessWidget {
//this is should be somewhere else but to keep things simple for you,
Future<List> fetchAds() async {
//the link you want to data from, goes inside get
final response = await http
.get('https://blasanka.github.io/watch-ads/lib/data/ads.json');
if (response.statusCode == 200) return json.decode(response.body);
return [];
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Dynamic height GridView Demo"),
),
body: FutureBuilder<List>(
future: fetchAds(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return new Padding(
padding: const EdgeInsets.all(4.0),
//this is what you actually need
child: new StaggeredGridView.count(
crossAxisCount: 4, // I only need two card horizontally
padding: const EdgeInsets.all(2.0),
children: snapshot.data.map<Widget>((item) {
//Do you need to go somewhere when you tap on this card, wrap using InkWell and add your route
return new AdCard(item);
}).toList(),
//Here is the place that we are getting flexible/ dynamic card for various images
staggeredTiles: snapshot.data
.map<StaggeredTile>((_) => StaggeredTile.fit(2))
.toList(),
mainAxisSpacing: 3.0,
crossAxisSpacing: 4.0, // add some space
),
);
} else {
return Center(
child:
new CircularProgressIndicator()); // If there are no data show this
}
}),
);
}
}
//This is actually not need to be a StatefulWidget but in case, I have it
class AdCard extends StatefulWidget {
AdCard(this.ad);
final ad;
_AdCardState createState() => _AdCardState();
}
class _AdCardState extends State<AdCard> {
//to keep things readable
var _ad;
String _imageUrl;
String _title;
String _price;
String _location;
void initState() {
setState(() {
_ad = widget.ad;
//if values are not null only we need to show them
_imageUrl = (_ad['imageUrl'] != '')
? _ad['imageUrl']
: 'https://uae.microless.com/cdn/no_image.jpg';
_title = (_ad['title'] != '') ? _ad['title'] : '';
_price = (_ad['price'] != '') ? _ad['price'] : '';
_location = (_ad['location'] != '') ? _ad['location'] : '';
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Card(
semanticContainer: false,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4.0)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Image.network(_imageUrl),
Text(_title),
Text('\$ $_price'),
Text(_location),
],
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
如果您有任何问题,这里是git 存储库中的完整示例。
祝你好运!
这里有两件事:
有一个现有的包来做这样的布局
为了使图像BoxFit.cover在DecorationImage小部件上看起来很好用。
这里的包 repo 中有大量示例
我只是使用了一些示例并将其修改为包含图片:
class GridViewExample extends StatefulWidget {
@override
_GridViewExampleState createState() => new _GridViewExampleState();
}
class _GridViewExampleState extends State<GridViewExample> {
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new Padding(
padding: const EdgeInsets.all(8.0),
child: new StaggeredGridView.countBuilder(
crossAxisCount: 4,
itemCount: 8,
itemBuilder: (BuildContext context, int index) => new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new NetworkImage("https://i.imgur.com/EVTkpZL.jpg"),
fit: BoxFit.cover
)
)
),
staggeredTileBuilder: (int index) =>
new StaggeredTile.count(2, index.isEven ? 2 : 1),
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
),),
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11789 次 |
| 最近记录: |