web-dev-qa-db-fra.com

Comment définir la hauteur personnalisée du widget dans GridView dans Flutter?

Même après avoir spécifié la hauteur de Container GridView, mon code produit des widgets carrés.

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<String> widgetList = ['A', 'B', 'C'];

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Container(
        child: new GridView.count(
          crossAxisCount: 2,
          controller: new ScrollController(keepScrollOffset: false),
          shrinkWrap: true,
          scrollDirection: Axis.vertical,
          children: widgetList.map((String value) {
            return new Container(
              height: 250.0,
              color: Colors.green,
              margin: new EdgeInsets.all(1.0),
              child: new Center(
                child: new Text(
                  value,
                  style: new TextStyle(fontSize: 50.0,color: Colors.white),
                ),
              ),
            );
          }).toList(),
        ),
      ),
    );
  }
}

La sortie du code ci-dessus est comme indiqué à gauche. Comment puis-je obtenir un GridView avec un widget de hauteur personnalisé, comme indiqué à droite?

 output  Required Output

9
AjayKumar

La clé est la ChildAspectRatio. Cette valeur est utilisée pour déterminer la mise en page dans GridView. Pour obtenir l'aspect souhaité, vous devez le définir sur (itemWidth/itemHeight). La solution serait la suivante:

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<String> widgetList = ['A', 'B', 'C'];

  @override
  Widget build(BuildContext context) {
    var size = MediaQuery.of(context).size;

    /*24 is for notification bar on Android*/
    final double itemHeight = (size.height - kToolbarHeight - 24) / 2;
    final double itemWidth = size.width / 2;

    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Container(
        child: new GridView.count(
          crossAxisCount: 2,
          childAspectRatio: (itemWidth / itemHeight),
          controller: new ScrollController(keepScrollOffset: false),
          shrinkWrap: true,
          scrollDirection: Axis.vertical,
          children: widgetList.map((String value) {
            return new Container(
              color: Colors.green,
              margin: new EdgeInsets.all(1.0),
              child: new Center(
                child: new Text(
                  value,
                  style: new TextStyle(
                    fontSize: 50.0,
                    color: Colors.white,
                  ),
                ),
              ),
            );
          }).toList(),
        ),
      ),
    );
  }
}
26

Il y a quelques jours, je suis venu ici pour trouver un moyen de modifier dynamiquement la hauteur lorsque des images sont chargées à partir d'Internet. Utiliser childAspectRatio ne peut pas le faire, car il s'applique à tous les widgets de GridView (même hauteur pour chaque).

Cette réponse peut aider quelqu'un qui souhaite une hauteur différente en fonction de chaque contenu de widget:

J'ai trouvé un paquet intitulé Flutter Staggered GridView de Romain Rastel . En utilisant ce paquet, nous pouvons faire beaucoup de choses en vérifiant les exemples ici.

Pour obtenir ce que nous voulons, nous pouvons utiliser StaggeredGridView.count() et sa propriété staggeredTiles: et pour sa valeur, vous pouvez mapper tous les widgets et appliquer StaggeredTile.fit(2).

Exemple de code:

StaggeredGridView.count(
    crossAxisCount: 4, // I only need two card horizontally
    padding: const EdgeInsets.all(2.0),
    children: yourList.map<Widget>((item) {
      //Do you need to go somewhere when you tap on this card, wrap using InkWell and add your route
      return new Card(
        child: Column(
          children: <Widget>[
             Image.network(item.yourImage),
             Text(yourList.yourText),//may be the structure of your data is different
          ],
        ),
      );
    }).toList(),

    //Here is the place that we are getting flexible/ dynamic card for various images
    staggeredTiles: yourList.map<StaggeredTile>((_) => StaggeredTile.fit(2))
        .toList(),
    mainAxisSpacing: 3.0,
    crossAxisSpacing: 4.0, // add some space
  ),
);

Vous pouvez trouver des exemples complets (copier, coller et exécuter) ici .

0
Blasanka