【问题标题】:cannot display gridview inside listview in my flutter demo app无法在我的颤振演示应用程序中的列表视图中显示网格视图
【发布时间】:2018-12-08 12:08:24
【问题描述】:

我正在将我的原生 android 项目转换为颤振应用程序,在此我需要在其他小部件下方显示选项网格。

这里是代码

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    Column homeThumb(String icon, String label) {
      Color color = Theme.of(context).primaryColor;

      return new Column(
        mainAxisSize: MainAxisSize.min,
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          new Container(
            margin: const EdgeInsets.all(8.0),
            child: new Image.asset(icon, width: 32.0, height: 32.0),
          ),
          new Container(
            margin: const EdgeInsets.only(top: 8.0),
            child: new Text(
              label,
              textAlign: TextAlign.center,
              style: new TextStyle(
                fontSize: 12.0,
                fontWeight: FontWeight.w400,
                color: color,
              ),
            ),
          ),
        ],
      );
    }

    Widget homeIcon = new Container(
        child: new Column(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: <Widget>[
          new Container(
              margin: const EdgeInsets.only(
                  top: 40.0, left: 8.0, right: 8.0, bottom: 8.0),
              child: new Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  homeThumb("images/icons/list.png", 'Claim Offers'),
                  homeThumb("images/icons/wallet.png", 'Wallet'),
                  homeThumb("images/icons/cart.png", 'Redeem Offers'),
                ],
              )),
          new Container(
              margin: const EdgeInsets.all(8.0),
              child: new Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  homeThumb("images/icons/user.png", 'Account'),
                  homeThumb("images/icons/badge.png", 'Merchants'),
                  homeThumb("images/icons/history.png", 'Shopping History'),
                ],
              )),
          new Container(
              margin: const EdgeInsets.all(8.0),
              child: new Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  homeThumb("images/icons/bell.png", 'Notifications'),
                  homeThumb("images/icons/plane.png", 'Service Request'),
                  homeThumb("images/icons/share.png", 'Share & Earn'),
                ],
              )),


        ]));

    Widget grid = new GridView.count(
      crossAxisCount: 4,
      children: new List<Widget>.generate(16, (index) {
        return new GridTile(
          child: new Card(
              color: Colors.blue.shade200,
              child: new Center(
                child: new Text('tile $index'),
              )
          ),
        );
      }),
    );

    return new MaterialApp(
      title: 'Minkville',
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Minkville'),
        ),
        body: new ListView(
          children: [
            new Image.asset(
              'images/slider/img_s1.jpg',
              width: 600.0,
              height: 180.0,
              fit: BoxFit.fill,
            ),
            homeIcon,
            grid

          ],
        ),
      ),
    );
  }
}

在调试时,以下日志即将到来

I/flutter (16594):引发了另一个异常:'package:flutter/src/rendering/sliver_multi_box_adaptor.dart':断言失败:第 441 行 pos 12:'child.hasSize':不正确。 I/flutter (16594):抛出另一个异常:RenderBox 未布置:RenderRepaintBoundary#199e9 relayoutBoundary=up3 NEEDS-PAINT

【问题讨论】:

标签: android dart flutter


【解决方案1】:

您需要将GridView 包装到Expanded 小部件中。更多关于 here.

【讨论】:

  • 你能举个例子吗?
【解决方案2】:

1。识别问题

new ListView(
  children: [
    new Image.asset(
      'images/slider/img_s1.jpg',
      width: 600.0,
      height: 180.0,
      fit: BoxFit.fill,
    ),
    homeIcon,
    grid // this is the problem
  ],
),

问题就在这里。因为网格定义为 GridView Widget,Flutter 不能 将其呈现为 ListView 的子项。

Widget grid = GridView.count(
      crossAxisCount: 4,
...

2。但我希望屏幕也可以滚动?

为此,我们需要替换 SingleChildScrollView 或类似的小部件,例如 ListView。 我们将其更改为 CustomScrollView

这是必要的,因为实际上,Flutter 可以识别两种模式:

  • 列表视图模式 垂直方向添加孩子

  • 网格框模式 将在 Z 方向添加孩子。如果它有两列,它的第一个和第二个孩子将在第一行呈现。然后它的第二行用第 3 和第 4 渲染。

官方文档

3。那段怎么写?

body: CustomScrollView( // replacement of SingleScrollChildView
  slivers: <Widget>[ // rather than children, it is named slivers
    // List Pattern section
    SliverList( // replacement of ListView
      delegate : // rather than children, it is named delegate
      ...
    ),
    // Grid Pattern section
    SliverGrid(
      delegate : // rather than children, it is named delegate
      ...
    ),

  ],
)

4。最终代码

  • ListView 更改为SliverList 以创建列表部分
  • CustomScrollView 包裹它
  • SliverGrid放在SliverList下面,这是我们的网格部分
  • 在 SliverGrid 内渲染我们的 grid 变量
body: new ListView( // replace this to SliverList
  children: [
    new Image.asset(
      'images/slider/img_s1.jpg',
      width: 600.0,
      height: 180.0,
      fit: BoxFit.fill,
    ),
    homeIcon,
    grid // needs to be moved into our Grid Section 

  ],
),
body: CustomScrollView(
  slivers: <Widget>[
    // A. This is our List Section
    SliverList(
      delegate: SliverChildListDelegate([
        Image.asset(
          'images/slider/img_s1.jpg',
          width: 600.0,
          height: 180.0,
          fit: BoxFit.fill,
        ),
        homeIcon,
        // grid
      ]),
    ),
    // B. This is our Grid Section
    SliverGrid.count(
      children: <Widget>[grid],
      crossAxisCount: 1,
    ),
  ],
),

演示

你可以使用这个 repo Github自己捆绑它

【讨论】:

    【解决方案3】:

    我最简单的例子没有CustomScrollView 没有SilverGrid 只是一个普通的ListView 和GridView。 这就是为什么我认为你不能直接将 gridView 放在 ListView 中,因为一旦你这样做了

    • 您无法区分是滚动列表还是网格,因为两者都是可滚动的。
    • ListView 需要一个小部件,因为它是可滚动的,所以它必须需要一个定义高度的小部件

    所以这里的工作是给它一个特定高度的小部件,所以如果你给它一个特定高度的容器并在容器内添加一个网格视图,那么这应该可以完成你的工作

    List<MaterialColor> gridColors = [
      Colors.red,
      Colors.deepPurple,
      Colors.green,
      Colors.deepOrange,
      Colors.red,
      Colors.deepPurple,
      Colors.green,
      Colors.deepOrange,
      Colors.red,
      Colors.deepPurple,
      Colors.green,
      Colors.deepOrange
    ];
    
    
    
      static Widget body() {
        return ListView(
          children: <Widget>[
            Container(
              height: 400,
              color: Colors.green,
            ),
            Container(
              height: 400,
              color: Colors.deepOrangeAccent,
              child: GridView.builder(
                  gridDelegate:
                      SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
                  itemCount: 8,
                  itemBuilder: (BuildContext context, int x) {
                    return Container(
                      margin: EdgeInsets.all(10),
                      height: 100,
                      width: 100,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(10),
                        color: gridColors[x],
                      ),
                    );
                  }),
            ),
            Container(
              height: 400,
              color: Colors.blue,
            ),
          ],
        );
      }
    

    这是输出希望它可以帮助某人

    【讨论】:

      【解决方案4】:

      忽略以上所有答案。 确保在ListViewGridView 中都设置了shrinkWrap : true。 问题解决了!!

      【讨论】:

      • 这正是我想要的。有很多小部件会自动拉伸高度,并且 shrinkWrap 的能力并不总是明确的。很高兴知道它存在于 GridView
      猜你喜欢
      • 2018-12-21
      • 1970-01-01
      • 2020-03-24
      • 1970-01-01
      • 2019-08-01
      • 1970-01-01
      • 2019-01-16
      • 2021-01-27
      • 1970-01-01
      相关资源
      最近更新 更多