it-swarm.com.de

Festlegen der benutzerdefinierten Höhe für das Widget in GridView in Flutter

Selbst nachdem ich die Höhe für Container GridView angegeben habe, erzeugt mein Code quadratische Widgets.

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(),
        ),
      ),
    );
  }
}

Die Ausgabe des obigen Codes ist wie links gezeigt. Wie bekomme ich ein GridView mit benutzerdefiniertem Höhen-Widget wie rechts gezeigt?

 output  Required Output

9
AjayKumar

Der Schlüssel ist das childAspectRatio. Dieser Wert wird verwendet, um das Layout in GridView zu bestimmen. Um den gewünschten Aspekt zu erhalten, müssen Sie ihn auf (itemWidth/itemHeight) setzen. Die Lösung wäre folgende:

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

Vor ein paar Tagen bin ich hierhergekommen, um eine Möglichkeit zu finden, die Höhe dynamisch zu ändern, wenn Bilder aus dem Internet geladen werden, und childAspectRatio kann dies nicht tun, da dies für alle Widget in GridView gilt (für jedes dieselbe Höhe).

Diese Antwort kann jemandem helfen, der für jeden Widget-Inhalt eine andere Höhe wünscht:

Ich habe ein Paket namens Flutter Staggered GridView von Romain Rastel gefunden. Mit diesem Paket können wir hier so viele Dinge überprüfen.

Um zu bekommen, was wir wollen, können wir StaggeredGridView.count() und seine Eigenschaft staggeredTiles: verwenden, und für seinen Wert können Sie alle Widgets zuordnen und StaggeredTile.fit(2) anwenden.

Beispielcode:

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
  ),
);

Ein vollständiges Beispiel (Kopieren, Einfügen und Ausführen) hier .

0
Blasanka

crossAxisCount, crossAxisSpacing und Bildschirmbreite bestimmen width und childAspectRatio bestimmen height.

Ich habe ein bisschen gerechnet, um die Beziehung zwischen ihnen herauszufinden.

var width = (screenWidth - ((_crossAxisCount - 1) * _crossAxisSpacing)) / _crossAxisCount;
var height = width / _aspectRatio;

Vollständiges Beispiel:

double _crossAxisSpacing = 8, _mainAxisSpacing = 12, _aspectRatio = 2;
int _crossAxisCount = 2;

@override
Widget build(BuildContext context) {
  double screenWidth = MediaQuery.of(context).size.width;

  var width = (screenWidth - ((_crossAxisCount - 1) * _crossAxisSpacing)) / _crossAxisCount;
  var height = width / _aspectRatio;

  return Scaffold(
    body: GridView.builder(
      itemCount: 10,
      itemBuilder: (context, index) => Container(color: Colors.blue[((index) % 9) * 100]),
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: _crossAxisCount,
        crossAxisSpacing: _crossAxisSpacing,
        mainAxisSpacing: _mainAxisSpacing,
        childAspectRatio: _aspectRatio,
      ),
    ),
  );
}
0
CopsOnRoad