带行的 ListView - 警告和错误

ListView with rows - Warnings and Errors

我正在制作一个 "infinite list",其中每个索引都有一行 2 张卡片。我想让这些卡片以上下文为中心,大小相同。所以两张卡片的宽度都是 totalWidth/2 - padding。但我没有得到想要的结果,这是我的初始代码:

new ListView.builder(
    padding: new EdgeInsets.all(8.0),
    itemExtent: 20.0,
    itemCount: gameList == null ? 2 : gameList.length,
    itemBuilder: (BuildContext context, int index) {
      if (index == 0) {
        return new RaisedButton(
          child: new Text("Click me!"),
          onPressed: () => getGames(),
        );
      } else if (index == 1) {
        return new Text("For new games");
      }
      return new Container(
        child: new Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Card(
              child: new Container(
                child: new Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    new Text(gameList[index*2]["name"])
                  ],
                ),
              ),
            ),
            new Card(
              child: new Container(
                child: new Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    new Text(gameList[index*2+1]["name"])
                  ],
                ),
              ),
            ),
          ],
        ),
      );
    },
  )

这导致了不需要的视觉结果和异常! 截屏:

异常:

I/flutter ( 3907): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY         
╞═════════════════════════════════════════════════════════
I/flutter ( 3907): The following RangeError was thrown during performLayout():
I/flutter ( 3907): RangeError (index): Invalid value: Not in range 0..49,     inclusive: 50
I/flutter ( 3907): When the exception was thrown, this was the stack:
I/flutter ( 3907): #0      List.[] (dart:core-patch/growable_array.dart:151)
I/flutter ( 3907): #1      _HomePageState.build.<anonymous closure>     (/data/user/0/com.yourcompany.gamerel/cache/gamerelyjhxqR/gamerel/lib/pages/home.dart:63:42)
I/flutter ( 3907): #2      SliverChildBuilderDelegate.build (package:flutter/src/widgets/sliver.dart:153:33)
I/flutter ( 3907): #3      SliverMultiBoxAdaptorElement._build.<anonymous closure> (package:flutter/src/widgets/sliver.dart:578:67)
I/flutter ( 3907): #4      _HashMap.putIfAbsent (dart:collection-patch/collection_patch.dart:131)
I/flutter ( 3907): #5      SliverMultiBoxAdaptorElement._build (package:flutter/src/widgets/sliver.dart:578:26)
I/flutter ( 3907): #6      SliverMultiBoxAdaptorElement.createChild.<anonymous closure> (package:flutter/src/widgets/sliver.dart:591:55)
I/flutter ( 3907): #7      BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2122:19)
I/flutter ( 3907): #8      SliverMultiBoxAdaptorElement.createChild (package:flutter/src/widgets/sliver.dart:584:11)
I/flutter ( 3907): #9      RenderSliverMultiBoxAdaptor.insertAndLayoutChild.<anonymous closure> (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:282:21)
I/flutter ( 3907): #10     RenderObject.invokeLayoutCallback.<anonymous closure> (package:flutter/src/rendering/object.dart:1937:58)
I/flutter ( 3907): #11     PipelineOwner._enableMutationsToDirtySubtrees (package:flutter/src/rendering/object.dart:1035:15)
I/flutter ( 3907): #12     RenderObject.invokeLayoutCallback (package:flutter/src/rendering/object.dart:1937:13)
I/flutter ( 3907): #13     RenderSliverMultiBoxAdaptor.insertAndLayoutChild (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:280:5)
I/flutter ( 3907): #14     RenderSliverFixedExtentBoxAdaptor.performLayout (package:flutter/src/rendering/sliver_fixed_extent_list.dart:166:17)
I/flutter ( 3907): #15     RenderObject.layout (package:flutter/src/rendering/object.dart:1841:7)
I/flutter ( 3907): #16     RenderSliverPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:144:11)
I/flutter ( 3907): #17     RenderObject.layout (package:flutter/src/rendering/object.dart:1841:7)
I/flutter ( 3907): #18     RenderViewportBase.layoutChildSequence (package:flutter/src/rendering/viewport.dart:248:13)
I/flutter ( 3907): #19     RenderViewport._attemptLayout (package:flutter/src/rendering/viewport.dart:882:12)
I/flutter ( 3907): #20     RenderViewport.performLayout (package:flutter/src/rendering/viewport.dart:806:20)
I/flutter ( 3907): #21     RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1718:7)
I/flutter ( 3907): #22     PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:1013:18)
I/flutter ( 3907): #23     BindingBase&SchedulerBinding&GestureBinding&ServicesBinding&RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:251:19)
I/flutter ( 3907): #24     BindingBase&SchedulerBinding&GestureBinding&ServicesBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:504:22)
I/flutter ( 3907): #25     BindingBase&SchedulerBinding&GestureBinding&ServicesBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:189:5)
I/flutter ( 3907): #26     BindingBase&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:688:15)
I/flutter ( 3907): #27     BindingBase&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:636:9)
I/flutter ( 3907): #28     _drawFrame (file:///b/build/slave/Linux_Engine/build/src/flutter/lib/ui/hooks.dart:70)
I/flutter ( 3907): The following RenderObject was being processed when the exception was fired:
I/flutter ( 3907):   RenderSliverFixedExtentList#1052375964 relayoutBoundary=up2 NEEDS-LAYOUT
I/flutter ( 3907):   creator: SliverFixedExtentList ← SliverPadding ← Viewport ← _ScrollableScope ←
I/flutter ( 3907):   IgnorePointer-[GlobalKey#486177627] ← Listener ← _GestureSemantics ←
I/flutter ( 3907):   RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#659063110] ← RepaintBoundary ←
I/flutter ( 3907):   CustomPaint ← RepaintBoundary ← NotificationListener<ScrollNotification> ← ⋯
I/flutter ( 3907):   parentData: paintOffset=Offset(8.0, 8.0) (can use size)
I/flutter ( 3907):   constraints: SliverConstraints(AxisDirection.down, GrowthDirection.forward, ScrollDirection.idle,
I/flutter ( 3907):   scrollOffset: 0.0, remainingPaintExtent: 595.4,     crossAxisExtent: 395.4, viewportMainAxisExtent:
I/flutter ( 3907):   603.4)
I/flutter ( 3907):   geometry: SliverGeometry(scrollExtent: 40.0, paintExtent: 40.0, maxPaintExtent: 40.0, )
I/flutter ( 3907):   currently live children: 0 to 24
I/flutter ( 3907): This RenderObject had the following descendants (showing up         to depth 5):
I/flutter ( 3907):   RenderRepaintBoundary#570038827
I/flutter ( 3907):     RenderConstrainedBox#1050372064
I/flutter ( 3907):       RenderPhysicalModel#158413069
I/flutter ( 3907):         _RenderInkFeatures#87489842
I/flutter ( 3907):           RenderSemanticsGestureHandler#431076252
I/flutter ( 3907):   RenderRepaintBoundary#551737634
I/flutter ( 3907):     RenderParagraph#594209207
I/flutter ( 3907):   RenderRepaintBoundary#766780884 NEEDS-PAINT
I/flutter ( 3907):     RenderFlex#923777135 NEEDS-PAINT
I/flutter ( 3907):       RenderPadding#893943236 relayoutBoundary=up1 NEEDS-PAINT
I/flutter ( 3907):         RenderPhysicalModel#618413979 relayoutBoundary=up2 NEEDS-PAINT
I/flutter ( 3907):           _RenderInkFeatures#994799987 relayoutBoundary=up3 NEEDS-PAINT
I/flutter ( 3907):       RenderPadding#698030940 relayoutBoundary=up1 NEEDS-PAINT
I/flutter ( 3907):         RenderPhysicalModel#956372272 relayoutBoundary=up2 NEEDS-PAINT
I/flutter ( 3907):           _RenderInkFeatures#434036791 relayoutBoundary=up3 NEEDS-PAINT
I/flutter ( 3907):   RenderRepaintBoundary#824949616 NEEDS-PAINT
I/flutter ( 3907):     RenderFlex#1033781722 NEEDS-PAINT
I/flutter ( 3907):       RenderPadding#207370496 relayoutBoundary=up1 NEEDS-PAINT
I/flutter ( 3907):         RenderPhysicalModel#1008320253 relayoutBoundary=up2 NEEDS-PAINT
I/flutter ( 3907):           _RenderInkFeatures#1069811468 relayoutBoundary=up3 NEEDS-PAINT
I/flutter ( 3907):       RenderPadding#206866148 relayoutBoundary=up1 NEEDS-PAINT
I/flutter ( 3907):         RenderPhysicalModel#533018794 relayoutBoundary=up2 NEEDS-PAINT
I/flutter ( 3907):           _RenderInkFeatures#262521214 relayoutBoundary=up3 NEEDS-PAINT
I/flutter ( 3907):   RenderRepaintBoundary#853196269 NEEDS-PAINT
I/flutter ( 3907):     RenderFlex#475430551 NEEDS-PAINT
I/flutter ( 3907):       RenderPadding#416695211 relayoutBoundary=up1 NEEDS-PAINT
I/flutter ( 3907):         RenderPhysicalModel#930790456 relayoutBoundary=up2 NEEDS-PAINT
I/flutter ( 3907):           _RenderInkFeatures#644301116 relayoutBoundary=up3 NEEDS-PAINT
I/flutter ( 3907): ════════════════════════════════════════════════════════════════════════════════════════════════════

我尝试在卡片的列中使用 CrossAxisAlignment.stretch,但这也导致了异常:

I/flutter ( 3907): The following RangeError was thrown during performLayout():
I/flutter ( 3907): RangeError (index): Invalid value: Not in range 0..49, inclusive: 50

请注意,这不是完全例外,但如果我也 post 的话,这个 post 会变得太长。但如果你需要,我会 post :)

如果你想使用ColumnRow,你可以使用一个Expanded来实现卡片的规则间距。但是,我认为您可能应该将 GridViewcrossAxisCount2 一起使用,因为它是专门用于有效布置方框网格的 class。

以下两种方法的代码。

使用GridView:

import 'package:flutter/material.dart';

void main() {
  runApp(new MaterialApp(
    home: new MyHomePage(),
  ));
}

List gameList = new List.generate(100, (int index) {
  return {
    'name': 'Game $index',
  };
});

class MyHomePage extends StatelessWidget {
  getGames() {
  }

  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("GridView example"),
      ),
      body: new GridView.builder(
        gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
          childAspectRatio: 3.0,
        ),
        itemCount: gameList.length,
        padding: new EdgeInsets.all(8.0),
        itemBuilder: (BuildContext context, int index) {
          return new Card(
            child: new Container(
              child: new Center(
                child: new Text(gameList[index]["name"]),
              ),
            ),
          );
        },
      ),
    );
  }
}

RowColumnExpanded 一起使用:

import 'package:flutter/material.dart';

void main() {
  runApp(new MaterialApp(
    home: new MyHomePage(),
  ));
}

List gameList = new List.generate(100, (int index) {
  return {
    'name': 'Game $index',
  };
});

class MyHomePage extends StatelessWidget {
  getGames() {
  }

  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Row and Column example"),
      ),
      body: new ListView.builder(
        padding: new EdgeInsets.all(8.0),
        itemExtent: 50.0,
        itemCount: (gameList.length / 2).ceil(),
        itemBuilder: (BuildContext context, int row) {
          return new Container(
            child: new Row(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: new List.generate(2, (int column) {
                return new Expanded(
                  child: new Card(
                    child: new Container(
                      child: new Center(
                        child: new Text(gameList[row * 2 + column]["name"]),
                      ),
                    ),
                  ),
                );
              }),
            ),
          );
        },
      ),
    );
  }
}