我正在制作一个“无限列表”,其中每个索引都有一行包含2张卡片的行。我想使这些卡的大小与上下文相同。因此,两个卡的宽度均为totalWidth / 2-填充。但是我没有得到想要的结果,这是我的初始代码:
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"])
],
),
),
),
],
),
);
},
)
这导致了不良的视觉效果和异常!
屏幕截图:
异常(exception):
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
请注意,这并不是全部异常(exception),但是如果我也将其发布,则这篇文章会花费太长时间。但是我会在需要时将其发布:)
最佳答案
如果要使用Column
和Row
,则可以使用Expanded
来实现卡片的规则间距。但是,我认为您可能应该将 GridView
与crossAxisCount
的2
一起使用,因为它是用于有效布置盒子网格的专门类。
下面的两种方法的代码。
使用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"]),
),
),
);
},
),
);
}
}
结合使用
Row
和Column
和Expanded
: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"]),
),
),
),
);
}),
),
);
},
),
);
}
}