无法在我的Flutter演示应用程序的listview中显示gridview

时间:2018-06-29 10:08:00

标签: android dart flutter

我正在将本机android项目转换为flutter应用程序,在这种情况下,我需要在其他小部件下方显示选项网格。

这是代码

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

4 个答案:

答案 0 :(得分:3)

忽略以上所有答案。 确保同时在shrinkWrap : trueListView中设置GridView。 问题解决了!

答案 1 :(得分:0)

您需要将GridView包装到Expanded小部件中。有关here的更多信息。

答案 2 :(得分:0)

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小部件,所以Flutter无法 将其呈现为ListView的子级。

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

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

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

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

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

  • 网格框样式 将在Z方向添加子项。如果它有两个列,则其第一个和第二个子代将在第一行上渲染。然后第二行用第三和第四渲染。

官方文档

CustomScroll

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

演示

Demo

您可以使用此仓库Github

自己捆绑它

答案 3 :(得分:0)

我最简单的示例,没有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,
        ),
      ],
    );
  }

输出结果希望对某人有帮助

enter image description here