Flutter - 具有无限高度错误的水平ListView
Flutter - Horizontal ListView with Unbounded height error
当 scrollDirection 设置为垂直时,它按预期工作。问题是当我将 section.axis 设置为 Axis.horizontal 以便 ListView 水平显示小部件时。
使用 Flexible 或 Expanded 小部件无法解决此问题,因为 ListView 的高度需要由列表中的小部件定义。
如您所见,shrinkWrap 也已启用。所以我不知道这里发生了什么,谢谢你的帮助。
控制台说:
'constraints.hasBoundedHeight': 不正确。
导致错误的相关小部件是:ListView
class SectionWidget extends StatelessWidget {
final Section section;
const SectionWidget({@required this.section});
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(section.title),
ListView.separated(
shrinkWrap: true,
scrollDirection: section.axis,
physics: section.axis == Axis.vertical
? NeverScrollableScrollPhysics()
: null,
itemCount: section.itemList.length,
itemBuilder: (BuildContext context, int index) {
return Container(
height: 100,
width: 100,
color: Colors.red,
); // Just to test if it works
},
separatorBuilder: (BuildContext context, int index) {
double paddingBetween = 10;
if (section.axis == Axis.horizontal) {
return SizedBox(width: paddingBetween);
} else {
return SizedBox(height: paddingBetween);
}
},
),
],
);
}
}
这是因为 Column 或 Row 提供了它们 children 需要的 height/width,而 ListView 从其 parent 中获取了尽可能多的 height/width。
要解决此问题,只需将 ListView 包装在容器中即可。像这样:
import 'package:flutter/material.dart';
class SectionWidget extends StatelessWidget {
final Section section;
const SectionWidget({@required this.section});
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(section.title),
Container(
height: section.axis == Axis.horizontal ? 100 : 700, // I just set these values
width: section.axis == Axis.horizontal ? 350 : 100, // to fit with my device.
child: ListView.separated( // If you want to fit for
shrinkWrap: true, // all devices, use MediaQuery
scrollDirection: section.axis,
physics: section.axis == Axis.vertical
? NeverScrollableScrollPhysics()
: null,
itemCount: section.itemList.length,
itemBuilder: (BuildContext context, int index) {
return Container(
height: 100,
width: 100,
color: Colors.red,
); // Just to test if it works
},
separatorBuilder: (BuildContext context, int index) {
double paddingBetween = 10;
if (section.axis == Axis.horizontal) {
return SizedBox(width: paddingBetween);
} else {
return SizedBox(height: paddingBetween);
}
},
),
),
],
);
}
}
的更多信息
编辑:
我认为使用 gridview 会更适合这个。我已经为你重新制作了构建代码以适应不同的 children 大小。 children 的定位和其他我认为你可以管理的东西。
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Expanded(
child: Text(section.title),
),
SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: GridView.builder(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 1),
shrinkWrap: true,
scrollDirection: section.axis,
physics: section.axis == Axis.vertical
? NeverScrollableScrollPhysics()
: null,
itemCount: section.itemList.length,
itemBuilder: (context, index) {
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
// Spacer(),
Container(
margin: EdgeInsets.all(10),
height: 100,
width: 100,
color: Colors.red,
),
// Spacer(),
],
);
},
),
),
],
);
}
当 scrollDirection 设置为垂直时,它按预期工作。问题是当我将 section.axis 设置为 Axis.horizontal 以便 ListView 水平显示小部件时。
使用 Flexible 或 Expanded 小部件无法解决此问题,因为 ListView 的高度需要由列表中的小部件定义。
如您所见,shrinkWrap 也已启用。所以我不知道这里发生了什么,谢谢你的帮助。
控制台说: 'constraints.hasBoundedHeight': 不正确。 导致错误的相关小部件是:ListView
class SectionWidget extends StatelessWidget {
final Section section;
const SectionWidget({@required this.section});
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(section.title),
ListView.separated(
shrinkWrap: true,
scrollDirection: section.axis,
physics: section.axis == Axis.vertical
? NeverScrollableScrollPhysics()
: null,
itemCount: section.itemList.length,
itemBuilder: (BuildContext context, int index) {
return Container(
height: 100,
width: 100,
color: Colors.red,
); // Just to test if it works
},
separatorBuilder: (BuildContext context, int index) {
double paddingBetween = 10;
if (section.axis == Axis.horizontal) {
return SizedBox(width: paddingBetween);
} else {
return SizedBox(height: paddingBetween);
}
},
),
],
);
}
}
这是因为 Column 或 Row 提供了它们 children 需要的 height/width,而 ListView 从其 parent 中获取了尽可能多的 height/width。
要解决此问题,只需将 ListView 包装在容器中即可。像这样:
import 'package:flutter/material.dart';
class SectionWidget extends StatelessWidget {
final Section section;
const SectionWidget({@required this.section});
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(section.title),
Container(
height: section.axis == Axis.horizontal ? 100 : 700, // I just set these values
width: section.axis == Axis.horizontal ? 350 : 100, // to fit with my device.
child: ListView.separated( // If you want to fit for
shrinkWrap: true, // all devices, use MediaQuery
scrollDirection: section.axis,
physics: section.axis == Axis.vertical
? NeverScrollableScrollPhysics()
: null,
itemCount: section.itemList.length,
itemBuilder: (BuildContext context, int index) {
return Container(
height: 100,
width: 100,
color: Colors.red,
); // Just to test if it works
},
separatorBuilder: (BuildContext context, int index) {
double paddingBetween = 10;
if (section.axis == Axis.horizontal) {
return SizedBox(width: paddingBetween);
} else {
return SizedBox(height: paddingBetween);
}
},
),
),
],
);
}
}
的更多信息
编辑:
我认为使用 gridview 会更适合这个。我已经为你重新制作了构建代码以适应不同的 children 大小。 children 的定位和其他我认为你可以管理的东西。
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Expanded(
child: Text(section.title),
),
SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: GridView.builder(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 1),
shrinkWrap: true,
scrollDirection: section.axis,
physics: section.axis == Axis.vertical
? NeverScrollableScrollPhysics()
: null,
itemCount: section.itemList.length,
itemBuilder: (context, index) {
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
// Spacer(),
Container(
margin: EdgeInsets.all(10),
height: 100,
width: 100,
color: Colors.red,
),
// Spacer(),
],
);
},
),
),
],
);
}