【问题标题】:Why is Gridview.count not filling out the space with my dynamic content为什么 Gridview.count 没有用我的动态内容填充空间
【发布时间】:2020-11-17 16:31:28
【问题描述】:

我正在尝试从第二列开始创建一个网格视图。第一张牌只是一张静态牌,里面有一个按钮。所以第二张牌的起始应该是动态的。

所有卡片的宽度和高度都相同。所以基本上它们都应该看起来像第一张卡片(添加一只新狗)

但它并没有像我预期的那样填满空间。

这是我正文部分的部分代码:

body: Stack(fit: StackFit.expand, children: [
      //bg image
      Container(
        decoration: BoxDecoration(
            image: DecorationImage(
                image: AssetImage(Images.bgYellow), fit: BoxFit.cover)),
      ),
      //content
      SafeArea(
        bottom: false,
        left: true,
        right: true,
        top: false,
        child: Padding(
            padding: EdgeInsets.all(3 * SizeConfig.safeBlockHorizontal),
            child: GridView.count(
                    crossAxisCount: 2,
                    children: [
                      //add card
                      Container(
                        margin: EdgeInsets.symmetric(
                            vertical: 1 * SizeConfig.blockSizeVertical,
                            horizontal: 2 * SizeConfig.blockSizeHorizontal),
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(30),
                          color: Colors.white,
                          boxShadow: [
                            BoxShadow(
                              color: Colors.grey.withOpacity(0.5),
                              spreadRadius: 2,
                              blurRadius: 8,
                              offset: Offset(
                                  0, 2), // changes position of shadow
                            ),
                          ],
                        ),
                        child: FlatButton(
                            onPressed: null,
                            child: Column(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: [
                                Icon(
                                  const IconData(0xe901,
                                      fontFamily: 'icDog'),
                                  color: muddyBrown,
                                  size: 20 * SizeConfig.safeBlockHorizontal,
                                ),
                                SizedBox(height: 5),
                                Text(
                                  "ADD A NEW  DOG",
                                  style: TextStyle(
                                      color: muddyBrown,
                                      fontWeight: FontWeight.bold,
                                      fontSize: 4 *
                                          SizeConfig.safeBlockHorizontal),
                                )
                              ],
                            )),
                      ),
                      //dynamic content
                      StateBuilder<PetState>(
                          observe: () => _petStateRM,
                          builder: (context, model) {
                            return Column(
                              children: [
                                ...model.state.pets.map((pet) =>
                                    GestureDetector(
                                      onTap: () {
                                        Navigator.pushNamed(
                                            context, petDetailRoute);
                                      },
                                      child: Container(
                                        margin: EdgeInsets.symmetric(
                                            vertical: 1 *
                                                SizeConfig
                                                    .blockSizeVertical,
                                            horizontal: 2 *
                                                SizeConfig
                                                    .blockSizeHorizontal),
                                        decoration: BoxDecoration(
                                          borderRadius:
                                              BorderRadius.circular(30),
                                          color: Colors.white,
                                          boxShadow: [
                                            BoxShadow(
                                              color: Colors.grey
                                                  .withOpacity(0.5),
                                              spreadRadius: 2,
                                              blurRadius: 8,
                                              offset: Offset(0,
                                                  2), // changes position of shadow
                                            ),
                                          ],
                                        ),
                                        child: Column(
                                          mainAxisAlignment:
                                              MainAxisAlignment.center,
                                          //dynamic data => Photo + Name
                                          children: [
                                            Container(
                                              width: 100.0,
                                              height: 100.0,
                                              decoration: new BoxDecoration(
                                                color:
                                                    const Color(0xff7c94b6),
                                                image: new DecorationImage(
                                                  image: new NetworkImage(
                                                      "${pet.photo}"),
                                                  fit: BoxFit.cover,
                                                ),
                                                borderRadius:
                                                    new BorderRadius.all(
                                                        new Radius.circular(
                                                            50.0)),
                                                border: new Border.all(
                                                  color: muddyBrown,
                                                  width: 4.0,
                                                ),
                                              ),
                                            ),
                                            SizedBox(height: 5),
                                            Text(
                                              "${pet.name}",
                                              style: TextStyle(
                                                  fontSize: 4 *
                                                      SizeConfig
                                                          .safeBlockHorizontal,
                                                  color: muddyBrown,
                                                  fontWeight:
                                                      FontWeight.bold),
                                            )
                                          ],
                                        ),
                                      ),
                                    ))
                              ],
                            );
                          }),
                    ],
                  )
                )),
    ]));

【问题讨论】:

  • 两张小卡片一定要一样大吗?
  • 是的,大小都一样。请注意,第一张卡片(添加狗)不是动态的。所以动态卡是第二张卡
  • 你说的是column,但是card的parent是A Row,你应该提一下动态网格视图需要沿哪个轴,沿交叉轴需要多少个children,请更新答案,或者您可以向我们展示所需的结果
  • 试着勾勒出你的最终解决方案,这样我们就可以对它有一个完整的了解,然后解决方案就来了!
  • 我只需要一个带有 2 个列的 gridview 并且行由动态内容决定

标签: flutter


【解决方案1】:

如果简单地将“静态”卡片添加到“动态”卡片,然后将它们全部一起构建一个GridView

Widget newDogButton = Card(...);

//dynamic content
StateBuilder<PetState>(
  observe: () => _petStateRM,
  builder: (context, model) {
    return Column(
      children: [
          newDogButton,
          ...model.state.pets.map((pet) =>  // ...

这应该会自动解决您的大部分布局问题。

【讨论】:

  • 按照你的建议做事并没有像我预期的那样工作 => imgur.com/a/GXn7j1Q
  • 对,Column 当然不应该是其中的一部分,抱歉。只需省略它,直接将卡片列表分配给 GridView 的子项。
【解决方案2】:

因为StateBuilder 返回一个小部件。把Whole GridView移到里面怎么样?

  ...
  child: Padding(
    padding: EdgeInsets.all(3 * SizeConfig.safeBlockHorizontal),
    child: StateBuilder<PetState>(
      observe: () => _petStateRM,
      builder: (context, model) {
        return GridView.count(
          crossAxisCount: 2,
          children: [

            // The button "ADD A NEW  DOG" here,
            Container(...),

            //dynamic content here
            ...model.state.pets.map((pet) =>

              ...

            ).toList(),

      },
    ),
  ),

【讨论】:

    【解决方案3】:

    GridView 中的每个网格项都将具有相同的高度和宽度,如果您希望不同的项具有不同的动态高度或宽度,请使用flutter_staggered_grid_view,在您的情况下:

    StaggeredGridView.countBuilder(
      crossAxisCount: 2,
      itemCount: 2,
      itemBuilder: (BuildContext context, int index) => new Container(
          color: Colors.green,
          child: new Center(
            child: new CircleAvatar(
              backgroundColor: Colors.white,
              child: new Text('$index'),
            ),
          )),
      staggeredTileBuilder: (int index) =>
          new StaggeredTile.count(1, index.isEven ? 2 : 1),
      mainAxisSpacing: 4.0,
      crossAxisSpacing: 4.0,
    )
    

    【讨论】:

      【解决方案4】:

      情况:
      对我来说,这个问题不是来自您的动态内容,而是来自height 允许它显示它的内容。在GridView.count 构造函数 中,默认的childAspectRatio 值为1.0,这意味着GridView 的每个孩子的默认最大高度为deviceWidth / crossAxisCount (在您的案例)

      问题:
      为了让每个孩子都能正确显示,它的高度不能超过这个比例(导致你的溢出错误)。

      我的看法:
      为了解决这个问题,我要么将动态内容StateBuilder&lt;PetState&gt;替换为高度不会超过比例的静态小部件,要么将动态内容StateBuilder&lt;PetState&gt;包裹在SingleChildScrollView中以确保不会发生overflowed错误并且包装器可以产生滚动效果来查看整个动态内容。

      【讨论】:

        猜你喜欢
        • 2011-04-20
        • 2012-05-01
        • 2017-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多