我正在尝试在Flutter中创建项目的水平滚动列表,我希望该列表仅根据其子项占用必要的高度。根据设计,“ListView
尝试扩展以适应其横向可用的空间”(来自Flutter docs),我也注意到它占据了视口的整个高度,但是有办法让它不这样做吗?理想情况下类似于此(显然不起作用):
new ListView(
scrollDirection: Axis.horizontal,
crossAxisSize: CrossAxisSize.min,
children: <Widget>[
new ListItem(),
new ListItem(),
// ...
],
);
我意识到,实现此目的的一种方法是将ListView
包裹在具有固定高度的Container
中。但是,我不一定知道物品的高度:
new Container(
height: 97.0,
child: new ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
new ListItem(),
new ListItem(),
// ...
],
),
);
我能够通过Row
将SingleChildScrollView
嵌套在Column
mainAxisSize: MainAxisSize.min
中,从而将“解决方案”合并在一起。但是,对我来说,这不是一个解决方案:
new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: new Row(
children: <Widget>[
new ListItem(),
new ListItem(),
// ...
],
),
),
],
);
答案 0 :(得分:8)
只需将shrink
的{{1}}属性设置为ListView
,它将适合空间而不是扩展。
示例:
true
答案 1 :(得分:5)
类似于 Gene 的回答,但我没有固定数量的小部件要添加。
您也不需要知道小部件的高度。
Widget _horizontalWrappedRow(List data) {
var list = <Widget>[Container(width: 16)]; // container is left padding
//create a new row widget for each data element
data.forEach((element) {
list.add(MyRowItemWidget(element));
});
// add the list of widgets to the Row as children
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: list,
),
);
}
答案 2 :(得分:4)
这与此处提出的问题非常相似:Flutter ListView.builder() widget's cross Axis is taking up the entire Screen height
我相信 ListViews 要求每个项目都具有相同的横轴大小。这意味着在这种情况下,我们无法为每个对象设置唯一的高度,交叉轴大小是固定的。
如果您想让子项本身唯一控制可滚动的高度,那么您可以使用 SingleChildScrollView 和 Row (注意:确保设置滚动方向:Axis.horizontal)
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: SafeArea(
child: Container(
// height: 100, // no need to specify here
color: Colors.white,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: <Widget>[
Container(
height: 300,
width: 300,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 100,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
width: 100,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
Container(
height: 300,
width: 300,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 100,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
width: 100,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
Container(
height: 300,
width: 300,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 100,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
width: 100,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
Container(
height: 300,
width: 300,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 100,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
width: 100,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
Container(
height: 300,
width: 300,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 100,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
width: 100,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
],
),
)),
),
),
);
}
}
答案 3 :(得分:3)
我使用的是容器的水平listview构建器,因此为了使容器不占据全部高度,我只用Center将其包裹起来即可,并且效果很好。
itemBuilder: (context, i){
return Center(child: word_on_line(titles[i]));
}
答案 4 :(得分:1)
使用扩展
Expanded(
child:ListView.separated(
shrinkWrap: true,
padding: EdgeInsets.all(10),
separatorBuilder: (BuildContext context, int index) {
return Align(
alignment: Alignment.centerRight,
child: Container(
height: 0.5,
width: MediaQuery.of(context).size.width / 1.3,
child: Divider(),
),
);
},
itemCount: dataMasterClass.length,
itemBuilder: (BuildContext context, int index) {
Datum datum = dataMasterClass[index];
return sendItem(datum);
},)
) ,
答案 5 :(得分:1)
用Column
和mainAxisSize: MainAxisSize.min
包装小部件对我来说很有效。您可以在此处尝试更改height
。
var data = [
{'name': 'Shopping', 'icon': Icons.local_shipping},
{'name': 'Service', 'icon': Icons.room_service},
{'name': 'Hotel', 'icon': Icons.hotel},
{'name': 'More', 'icon': Icons.more}
];
new Container(
constraints: new BoxConstraints(
minHeight: 40.0,
maxHeight: 60.0,
),
color: Colors.transparent,
child: new ListView(
scrollDirection: Axis.horizontal,
children: data
.map<Widget>((e) => Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Container(
width: 40,
height: 50, // try to change this.
color: Colors.transparent,
margin: EdgeInsets.only(right: 20, left: 4),
child: ClipOval(
child: Container(
padding: EdgeInsets.all(4),
color: Colors.white,
child: Icon(
e["icon"],
color: Colors.grey,
size: 30,
),
),
),
),
],
))
.toList(),
));
答案 6 :(得分:1)
通过应用上述所有解决方案,尚未找到合适的答案,如果我们不知道高度,这将帮助我们设置水平Listview。在所有情况下都必须设置高度。因此我应用了下面的解决方案,该解决方案对我有用,而无需为列表项指定任何高度。 @sindrenm在他的问题中已经提到过。所以我想继续研究直到找到可行的解决方案。我应用了wrapWrap:true,但是它将沿主轴收缩ListView。 (仅适用于垂直scrollView),并且不沿问题中的要求沿横轴显示。因此在不久的将来,任何人都可以在生产中使用此解决方案,它对我所有的水平清单都非常有用。
//below declared somewhere in a class above any method and assume list has filled from some API.
var mylist = List<myModel>();
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
for (int index = 0; index < mylist.length; index++)
listItem(mylist[index]);
],
),
),
),
listItem(){
return Column(
children[
widget1(),
widget2().... etc..
]);
}
答案 7 :(得分:1)
据我了解,您不能在垂直ListView内拥有水平ListView并动态设置其高度。如果您的要求允许(不允许无限滚动,少量元素等),则可以改用SingleChildScrollView。
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [...],
),
);
答案 8 :(得分:0)
使用ConstrainedBox
设置minHeight
和maxHeight
ConstrainedBox(
constraints: new BoxConstraints(
minHeight: 35.0,
maxHeight: 160.0,
),
child: new ListView(
shrinkWrap: true,
children: <Widget>[
new ListItem(),
new ListItem(),
],
),
)
答案 9 :(得分:0)
如果您不希望 listview 强制您的小部件适合横轴,请确保将它们放置在 Column() 或 Row() 小部件中,而不是直接将其放置在 listview() 中
Image img = ImageIO.read(new File("background.jpg");
public void paint(Graphics g)
{
// Draw the previously loaded image to Component.
g.drawImage(img, 0, 0, null);
}