列中的扩展listview占用了额外的空间

时间:2018-10-06 20:31:27

标签: listview flutter

我在一列中有两个列表视图。我希望第一个listview占用尽可能少的空间。因此,如果列表中只有一项,则包含listview的框的大小应为一项高。
我试图为ListView使用容器,但是随后出现错误,告诉我使用FitFit.loose使用Expanded或Flexible。使用它们的问题在于,它们都会导致ListView额外填充。

The red in this screenshot is the problem

在此屏幕截图中,您可以在第一个请求下看到一些红色。那是包含我的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()));
        }));

}

4 个答案:

答案 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(
                       
                        );
                      },
                    ),