如何在Flutter中为GridView.builder计算childAspectRatio [英] How to calculate childAspectRatio for GridView.builder in flutter

查看:194
本文介绍了如何在Flutter中为GridView.builder计算childAspectRatio的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

类别网格,其中图像和类别名称显示在图像下方

Grid of categories with image and category name displayed below the image

 Widget build(BuildContext context) {
return FutureBuilder(
    future: categoriesService.getCategories(1),
    builder: (BuildContext context, AsyncSnapshot snapshot) {
      if (snapshot.connectionState == ConnectionState.done) {
        if (snapshot.error != null) {
          print('error ${snapshot.error}');
          return Text(snapshot.error.toString());
        }
        // YOUR CUSTOM CODE GOES HERE
        return Container(
          // padding: const EdgeInsets.all(0.0),
          child: GridView.builder(
            physics: NeverScrollableScrollPhysics(),
            shrinkWrap: true,
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 3,
              // childAspectRatio: 19 / 12,
              mainAxisSpacing: 10.0,
              crossAxisSpacing: 10.0,
            ),
            itemCount: snapshot.data.length,
            itemBuilder: (context, index) {
              Category category = snapshot.data[index];
              return Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisAlignment: MainAxisAlignment.start,
                children: <Widget>[
                  Container(
                    child: Image.network(
                      category.image,
                      fit: BoxFit.cover,
                    ),
                    decoration: BoxDecoration(
                      border: Border.all(width: 1.0),
                    ),
                  ),
                  Text(category.name)
                ],
              );
            },
          ),
        );
      } else {
        return new CircularProgressIndicator();
      }
    });

}

我的子项具有图像和类别名称.如图所示,当前子项正在溢出,我们无法在图像下方看到类别名称,并且无法删除图像和边框之间的顶部空间.

My child item has an image and category name. as seen in the image, currently child item is overflowing and we cant see the category name below the image, and unable to remove top space between image and border.

原始设计在这里

推荐答案

我找到了一种动态设置最大子项的长宽比到Grid视图的方法.它是如何工作的 ?首先,请查看此答案.我们如何在 overlayEntery

I find a way to set aspect ratio of biggest child to our Grid view dynamicly. how it work ? First please Look at this answer for . how we can find size of a widget during the build with overlayEntery

如何获取小部件的高度?

之后,我们在childAspectRatio中的网格视图中设置正确的宽高比(使用overlayEntery测量).

after that we set the right aspect ratio (Measured with overlayEntery ) to our Grid View in childAspectRatio.

希望这对您有所帮助.

我做个例子...

https://dartpad.dev/4821d71ec618d7d1f1f92f27458fde61

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}
class GridItemModel {
  String longtext;
  GlobalKey itemKey;
  double width;
  double height;
  GridItemModel(this.longtext) {
    itemKey = GlobalKey();
  }
}
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }

}
class MyHomePage extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return _StateHomePage();
  }

}

class _StateHomePage extends State<MyHomePage> {
  // this first assign very important don't change it .
  // if you change this part overlayEntry cant find biggest widget correctly .(cant see not scrolled items.)
  // for test change to 1/1 and see what happening.
  var myDynamicAspectRatio = 1000 / 1;
  OverlayEntry sticky;
  List<GridItemModel> myGridList = new List();
  double maxHeight = 0;
  double maxWidth = 0;

  @override
  void initState() {
    if (sticky != null) {
      sticky.remove();
    }
    sticky = OverlayEntry(
      builder: (context) => stickyBuilder(context),
    );

    WidgetsBinding.instance.addPostFrameCallback((_) {
      Overlay.of(context).insert(sticky);
      setState(() {});
    });
    super.initState();
  }

  @override
  void dispose() {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      sticky.remove();
    });
    super.dispose();
  }


  @override
  Widget build(BuildContext context) {
    final title = 'Grid List';
    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(
          title: Text(title),
        ),
        body: GridView.count(
            crossAxisCount: 2,
            childAspectRatio: myDynamicAspectRatio,
            children: List.generate(20, (index) {
              myGridList.add(new GridItemModel(longTextMaker(index)));
              return Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  Container(
                    key: myGridList[index].itemKey,
                    decoration: BoxDecoration(
                      border: Border.all(color: Colors.black),
                      color: Colors.teal[index*100]
                    ),
                    child: Text(
                      'Item $index' + myGridList[index].longtext,
                      style: Theme.of(context).textTheme.headline5,
                    ),
                  ),
                ],
              );
            }),
          ),
        ),
    );
  }
  String longTextMaker(int count){
    String  result = "longText";
    for(int i = 0 ; i < count; i++){
      result += "longText" ;
    }
    return result;
  }
  shouldUpdateGridList(){
    bool isChanged =false;
    for(GridItemModel gi in myGridList) {
      if(gi.width != null) {
        if (gi.height > maxHeight) {
          maxHeight = gi.height;
          maxWidth = gi.width;
          isChanged = true;
        }
      }
    }
    if(isChanged) {
        myDynamicAspectRatio = maxWidth / maxHeight;
        print("AspectRatio" + myDynamicAspectRatio.toString());
    }
  }

  Widget stickyBuilder(BuildContext context) {
    for(GridItemModel gi in myGridList) {
      if(gi.width == null) {
        final keyContext = gi.itemKey.currentContext;
        if (keyContext != null) {
          final box = keyContext.findRenderObject() as RenderBox;
          print(box.size.height);
          print(box.size.width);
          gi.width = box.size.width;
          gi.height = box.size.height;
        }
      }
    }
    shouldUpdateGridList();
    return Container();
  }
}

这篇关于如何在Flutter中为GridView.builder计算childAspectRatio的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆