web-dev-qa-db-ja.com

FlutterのGridViewでウィジェットのカスタムの高さを設定する方法は?

Container GridViewの高さを指定した後でも、私のコードは正方形のウィジェットを作成しています。

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

上記のコードの出力は、左に示すとおりです。右側に示すように、カスタムの高さウィジェットを持つGridViewを取得するにはどうすればよいですか?

outputRequired Output

21
AjayKumar

キーはchildAspectRatioです。この値は、GridViewのレイアウトを決定するために使用されます。目的のアスペクトを取得するには、(itemWidth/itemHeight)に設定する必要があります。解決策は次のとおりです。

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

数日前、インターネットから画像が読み込まれたときに動的に高さを変更する方法を見つけるためにここに来ましたが、childAspectRatioを使用してもそれはできません。

この答えは、すべてのウィジェットコンテンツに応じて異なる高さを希望する人に役立つ場合があります。

Romain RastelによるFlutter Staggered GridView というパッケージを見つけました。このパッケージを使用して、ここで例を確認することができます。

必要なものを取得するには、StaggeredGridView.count()とそのプロパティstaggeredTiles:を使用します。その値には、すべてのウィジェットをマップし、StaggeredTile.fit(2)を適用できます。

サンプルコード:

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

完全な例(コピー、貼り付け、実行) here を見つけることができます。

3
Blasanka

crossAxisCountcrossAxisSpacing、および画面の幅がwidthを決定し、childAspectRatioheightを決定します。

それらの関係を理解するために少し計算しました。

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

完全な例:

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