Siéntete en la libertad de compartir nuestra página y códigos con otro, ayúdanos a hacer crecer nuestra comunidad.
Solución:
Editar: Agregué el constructor StaggeredTile.fit
en el 0.2.0. Con eso, debería poder crear su aplicación ;-).
Primer comentario:
Por ahora, con StaggeredGridView, el diseño y la representación de los niños son completamente independientes. Entonces, como dijo @rmtmckenzie, tendrá que obtener el tamaño de la imagen para crear sus mosaicos. Entonces puedes usar StaggeredTile.count
constructor con un valor doble para el mainAxisCellCount
parámetro: new StaggeredTile.count(x, x*h/w)
(donde h
es la altura de tu imagen y w
su ancho. Para que el mosaico tenga la misma relación de aspecto que su imagen.
Lo que desea lograr necesitará más trabajo porque desea tener un área debajo de la imagen con algo de información. Para eso, creo que tendrá que calcular el ancho real de su mosaico antes de crearlo y usar el StaggeredTile.extent
constructor.
Entiendo que esto no es ideal y actualmente estoy trabajando en una nueva forma de crear el diseño. Espero que te ayude a construir escenarios como el tuyo.
Primero déjame contarte cómo terminé aquí:
En mi aplicación, quería una vista de cuadrícula para mostrar mis tarjetas publicitarias y todos los datos que provienen de la base de datos del servidor y las imágenes provienen del servidor y las imágenes tienen diferentes tamaños. solía FutureBuilder
para mapear esos datos a GridView
. Primero intenté usar:
double cardWidth = MediaQuery.of(context).size.width / 3.3;
double cardHeight = MediaQuery.of(context).size.height / 3.6;
//....
GridView.count(
childAspectRatio: cardWidth / cardHeight,
//..
Como puede ver, no será dinámico para todas las tarjetas. Vine aquí como tú e intenté usar todas las respuestas, esas son geniales y tienes que abordar un poco para entender cómo, pero cualquiera de esas respuestas resolvió completamente mi problema.
Utilizando @RomainRastel respuesta y gracias a su StaggeredGridView
paquete. Tuve que usar StaggeredGridView.count
como mi constructor para mapear todas las cartas y para el staggeredTiles
propiedad tuve que volver a mapear todas las tarjetas y agregar para cada StaggeredTile.fit(2)
.
Estoy seguro de que todavía no lo entendiste, así que probemos con un ejemplo simple para que no tengas que ir a otro lugar para encontrar una respuesta:
Primero agregue dependencia a pubspec.yaml
, ahora la versión es 0.2.5
. Puede consultar el último aquí.
dependencies:
flutter_staggered_grid_view: ^0.2.5
Si está obteniendo datos de Internet o si va a copiar y pegar este ejemplo, también debe agregar esta dependencia: 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 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(
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((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.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
//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: [
Image.network(_imageUrl),
Text(_title),
Text('$ $_price'),
Text(_location),
],
),
);
Si tiene algún problema, aquí hay un ejemplo completo en un repositorio de git.
¡Buena suerte!
Aquí hay dos cosas:
-
Hay un paquete existente para hacer tal diseño.
-
Para hacer el las imágenes se ven bien usar
BoxFit.cover
sobre elDecorationImage
widget.
Hay toneladas de ejemplos en el repositorio de paquetes aquí.
Acabo de usar uno de los ejemplos y lo modifiqué para incluir imágenes:
class GridViewExample extends StatefulWidget
@override
_GridViewExampleState createState() => new _GridViewExampleState();
class _GridViewExampleState extends State
@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,
),),
);
Puntuaciones y reseñas
Al final de la post puedes encontrar las crónicas de otros creadores, tú igualmente eres capaz dejar el tuyo si lo crees conveniente.