无法在我的颤振演示应用程序中的列表视图中显示网格视图

Posted

技术标签:

【中文标题】无法在我的颤振演示应用程序中的列表视图中显示网格视图【英文标题】: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

【问题讨论】:

看看我的回答***.com/questions/50095763/… 【参考方案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

以上是关于无法在我的颤振演示应用程序中的列表视图中显示网格视图的主要内容,如果未能解决你的问题,请参考以下文章

我在 firebase 的列表中有一系列项目。我想在我的颤振应用程序中显示这些数组元素,但我失败了

单击特定网格视图单元格时淡出网格视图

动画列表中的颤振关闭项目无法正常工作

无法通过 imageloader 类在列表视图中显示图像

Android - 网格视图或列表视图?

如何从 Flutter 中的网格视图计数访问生成列表中的特定单元格?