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 erfolgt wie links gezeigt. Wie kann ich eine GridView mit einem benutzerdefinierten Höhen-Widget erhalten, wie rechts gezeigt?
Antworten:
Der Schlüssel ist der
childAspectRatio
. Dieser Wert wird verwendet, um das Layout in zu bestimmenGridView
. 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(), ), ), ); } }
quelle
GridView.builder
undSliverGridDelegateWithFixedCrossAxisCount
dannchildAspectRatio
auf demgridDelegate
Vor ein paar Tagen bin ich hierher gekommen, um eine Möglichkeit zu finden, die Höhe dynamisch zu ändern, wenn Bilder aus dem Internet geladen werden, und dies
childAspectRatio
kann nicht verwendet werden, da dies für alle Widgets in GridView gilt (jeweils dieselbe Höhe).Diese Antwort kann jemandem helfen, der je nach Widget-Inhalt unterschiedliche Höhen haben möchte:
Ich habe ein Paket namens Flutter Staggered GridView von Romain Rastel gefunden . Mit diesem Paket können wir so viele Dinge tun, um Beispiele hier zu überprüfen.
Um das zu bekommen, was wir wollen, können wir
StaggeredGridView.count()
und seine Eigenschaft verwendenstaggeredTiles:
und für seinen Wert können Sie alle Widgets zuordnen und anwendenStaggeredTile.fit(2)
.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) finden Sie hier .
quelle
crossAxisCount
,crossAxisSpacing
Und die Bildschirmbreite bestimmenwidth
, undchildAspectRatio
bestimmtheight
.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, ), ), ); }
quelle
Es funktioniert für mich.
Beispielcode:
var _crossAxisSpacing = 8; var _screenWidth = MediaQuery.of(context).size.width; var _crossAxisCount = 2; var _width = ( _screenWidth - ((_crossAxisCount - 1) * _crossAxisSpacing)) / _crossAxisCount; var cellHeight = 60; var _aspectRatio = _width /cellHeight;
Rasteransicht:
GridView.builder( padding: EdgeInsets.only( left: 5.0, right: 5.0, top: 10, bottom: 10), shrinkWrap: false, itemCount: searchList.length, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: _crossAxisCount,childAspectRatio: _aspectRatio), itemBuilder: (context, index) { final item = searchList[index]; return Card( child: ListTile( title: Text(item.name,maxLines: 1,overflow: TextOverflow.ellipsis), trailing: Container( width: 15, height: 15, decoration: BoxDecoration( color: item.isActive == true ? Theme.of(context).primaryColor : Colors.red, borderRadius: BorderRadius.all( Radius.circular(50))), ), onTap: () { }, ), elevation: 0.5, ); }, )
quelle