我在一列中有两个列表视图。我希望第一个listview占用尽可能少的空间。因此,如果列表中只有一项,则包含listview的框的大小应为一项高。
我试图为ListView使用容器,但是随后出现错误,告诉我使用FitFit.loose使用Expanded或Flexible。使用它们的问题在于,它们都会导致ListView额外填充。
在此屏幕截图中,您可以在第一个请求下看到一些红色。那是包含我的ListView的Expanded的一部分。
这是我的代码:
return new Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
appBar: new PreferredSize(
child: GradientAppBar(includeLogo: false),
preferredSize: new Size.fromHeight(75.0),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 10.0, top: 0.0),
child: TextField(
onChanged: (text) {
setState(() {
_searchText = text;
});
print("search text: $text");
},
decoration: new InputDecoration(
hintText: 'Search',
contentPadding: const EdgeInsets.symmetric(vertical: 20.0),
border: InputBorder.none,
hintStyle: new TextStyle(
color: Theme.of(context).secondaryHeaderColor),
icon: new Icon(searchIcon,
color: Theme.of(context).secondaryHeaderColor)),
)),
FutureBuilder<FriendRequests>(
future: fetchFriendRequests(),
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data.friendRequests.length > 0) {
return Flexible(
child: Column(mainAxisSize: MainAxisSize.min, children: <
Widget>[
Container(
padding: EdgeInsets.all(15.0),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Theme.of(context).bottomAppBarColor,
border: new Border(
bottom: new BorderSide(
color: Theme.of(context).accentColor,
width: 1.0,
style: BorderStyle.solid),
top: new BorderSide(
color: Theme.of(context).accentColor,
width: 1.0,
style: BorderStyle.solid))),
child: Center(child: Text("Requests"))),
Flexible(
child: Container(
decoration: new BoxDecoration(
color: Colors.red,
),
child: new ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data.friendRequests.length,
itemBuilder: (BuildContext context, int index) {
return new Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Container(
decoration: new BoxDecoration(
color:
Theme.of(context).backgroundColor,
border: new Border.all(
color:
Theme.of(context).accentColor)),
child: new FriendRequestView(
snapshot.data.friendRequests[index]
.friendName,
snapshot.data.friendRequests[index]
.pictureURL,
snapshot.data.friendRequests[index].id,
snapshot.data.friendRequests[index]
.creationDate),
)
],
);
},
)))
]));
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
} else if (snapshot.hasData &&
snapshot.data.friendRequests.length == 0) {
return Container();
}
// By default, show a loading spinner
return Center(child: CircularProgressIndicator());
},
),
Container(
padding: EdgeInsets.all(15.0),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Theme.of(context).bottomAppBarColor,
border: new Border(
bottom: new BorderSide(
color: Theme.of(context).accentColor,
width: 1.0,
style: BorderStyle.solid),
top: new BorderSide(
color: Theme.of(context).accentColor,
width: 1.0,
style: BorderStyle.solid))),
child: Center(child: Text("Suggestions"))),
FriendSuggestionsView(
searchText: _searchText,
)
],
),
);
这是我的FriendSuggestions视图:
Widget build(BuildContext context) {
return Flexible(
child: FutureBuilder<FriendSuggestions>(
future: fetchSuggestions(),
builder: (context, snapshot) {
if (snapshot.hasData &&
snapshot.data.friendSuggestions.length > 0) {
return new ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data.friendSuggestions.length,
itemBuilder: (BuildContext context, int index) {
return FriendSuggestionRow(
name: snapshot.data.friendSuggestions[index].name,
userID: snapshot.data.friendSuggestions[index].userID,
pictureURL: snapshot
.data.friendSuggestions[index].pictureURL);
});
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
} else if (snapshot.hasData &&
snapshot.data.friendSuggestions.length == 0) {
return Container(
padding: EdgeInsets.all(20.0),
child: Center(child: Text("No suggestions")));
}
// By default, show a loading spinner
return Container(
padding: EdgeInsets.all(20.0),
child: Center(child: CircularProgressIndicator()));
}));
}
答案 0 :(得分:4)
我遇到了同样的问题,经过一些研究后,我找到了一个对我有用的解决方案: 您必须为padding属性指定EdgeInsets.zero。
答案 1 :(得分:2)
在FutureBuilder
下,您应该使用Flexible
容器而不是Expanded
,以防止其子代占用过多空间。生成请求 true
时,还需要将shrinkWrap属性设置为ListView
。但是,请注意文档的最后一段:
收缩包装滚动视图的内容比扩展到允许的最大尺寸(...)要昂贵得多。
更新:
根据提供的其他信息,这是如何防止建议与请求重叠的方法。
@override
Widget build(BuildContext context) {
return Scaffold(
..., // other scaffold properties
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.max,
children: [
..., // search field widget
Expanded(
child: LayoutBuilder(
builder: (context, constraints) => Column(children: [
LimitedBox(
maxHeight: constraints.maxHeight / 2,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
..., // requests header widget
FutureBuilder<FriendRequests>(
future: fetchFriendRequests(),
builder: (context, snapshot) {
if (snapshot.hasData &&
snapshot.data.friendRequests.length > 0) {
return Flexible(
child: Container(
..., // box decoration
child: new ListView.builder(
shrinkWrap: true,
..., // item count and builder
),
),
);
} else ... // handle other data states
},
),
],
),
),
Expanded(
child: Column(
children: [
..., // suggestions header widget
FutureBuilder<FriendSuggestions>(
future: fetchSuggestions(),
builder: (context, snapshot) {
if (snapshot.hasData &&
snapshot.data.friendSuggestions.length > 0) {
return Expanded(
child: new ListView.builder(
..., // item count and builder
),
);
} else ... // handle other data states
},
),
],
),
),
]),
),
),
],
),
);
}
答案 2 :(得分:0)
这通常会从列表视图中删除多余的顶部填充:
MediaQuery.removePadding(
context:context,
removeTop: true,
child ListView.Builder(
itemCount:2,
itemBuilder(context,index){
});
答案 3 :(得分:0)
在padding: EdgeInsets.zero,
中使用ListView.builder
ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: 3,
physics: ScrollPhysics(),
itemBuilder: (context, index) {
return Container(
);
},
),