Flutter - 如何在 flutter 中使用列表视图将滚动视图添加到列

Flutter - How to add scrollview to column with listview in flutter

我有一个带有一列的容器,该列包含三个容器和一个用展开包裹的列表视图,效果很好,但我正在尝试向整个容器添加一个滚动视图,以便在三个带有列表视图的滚动条上,请问我该如何做实现这个?下面是我的代码的样子。


List<Content> content = [];

_fetchComments() async {
    setState(() {
      isLoading = true;
      _isDealButtonRefresh = true;
    });

    try {
      final result = await InternetAddress.lookup('google.com');
      if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
        print('connected');

        String baseURL;

        debugPrint("my select:$_mySelection");

        if (_mySelection == null && _myFeatureSelection == null) {
          baseURL = "myjson link";
          
        } else if (_myFeatureSelection != null) {
          baseURL =
              "my json link" +
                  _myFeatureSelection;
          debugPrint("feature enter");

          _mySelection = null;
        } else if (_mySelection != null && _myFeatureSelection == null) {
          baseURL = "my json link" +
              _mySelection;
          
        }

        print("our url:$baseURL");

        final response = await http.get(baseURL);
        if (response.statusCode == 200) {
          print(response.body);
          content = (json.decode(response.body) as List)
              .map((data) => new Content.fromJson(data))
              .toList();
          setState(() {
            print(response.body);
            isLoading = false;
            _isDealButtonRefresh = false;
          });
        } else {
          print(response.body);
          throw Exception('Failed to load post');
        }
      }
    } on SocketException catch (_) {
      print('not connected');
      setState(() => isLoading = false);

      Navigator.pushReplacement(
          context,
          new MaterialPageRoute(
              builder: (BuildContext context) => NoInternet()));

    }
  }

initState() {
    super.initState();
_fetchComments();
  }

body: Container(
        child: Column(children: <Widget>[

Container(),

Container(),

Container(),

Expanded(child: ListView.separated(
                                                separatorBuilder:
                                                    (context, index) => Divider(
                                                          color: Colors.grey,
                                                        ),
                                                
                                                itemCount: content == null
                                                    ? 0
                                                    : _searchResult.length,
                                                itemBuilder:
                                                    (context, position) {
                                                  final current =
                                                      _searchResult[position];
                                                  double myrate = double.parse(
                                                      _searchResult[position]
                                                                  .ratings ==
                                                              null
                                                          ? "0"
                                                          : _searchResult[position]
                                                              .ratings);
                                                  debugPrint("rato:$myrate");
                                                  return FutureBuilder<String>(
                                                      future: getDistance(
                                                              current.lat,
                                                              current.lng)
                                                          .then((value) =>
                                                              value.toString()),
                                                      builder:
                                                          (context, snapshot) {
                                                        return Container(
                                                           
                                                            child:
                                                                GestureDetector(
                                                                    onTap: () {
                                                                      Navigator.push(
                                                                          context,
                                                                          CupertinoPageRoute(
                                                                              builder: (BuildContext ctx) => Maps(_searchResult[position])));
                                                                    },
                                                                    child:
                                                                        Column(
                                                                      children: <
                                                                          Widget>[
                                                                        Row(
                                                                          children: <
                                                                              Widget>[
                                                                            Expanded(
                                                                                child:Container(
                                                                                  height:150,
                                                                                  width: MediaQuery.of(context).size.width,

                                                                                  child: SizedBox(
                                                                                    child: FadeInImage(image: NetworkImage(_searchResult[position].thumbnail_name), placeholder: AssetImage("assets/640x360.png"),
                                                                                      fit: BoxFit.cover,),
                                                                                  ),
                                                                                )),
                                                                          ],
                                                                        ), 

                                                                        Container(
                                                                          padding:
                                                                              const EdgeInsets.all(5.0),
                                                                          child:
                                                                              Row(
                                                                            crossAxisAlignment:
                                                                                CrossAxisAlignment.start,
                                                                            children: <Widget>[
                                                                              Expanded(
                                                                                child: Column(
                                                                                  children: <Widget>[
                                                                                    Container(
                                                                                      padding: const EdgeInsets.only(bottom: 1.0),
                                                                                      child: Text(
                                                                                        _searchResult[position].title,
                                                                                        style: TextStyle(fontFamily: 'Montserrat', fontSize: 13, fontWeight: FontWeight.bold),
                                                                                      ),
                                                                                    ),
                                                                                    Container(
                                                                                      padding: const EdgeInsets.only(bottom: 1.0),
                                                                                      child: Text(
                                                                                        _searchResult[position].address,
                                                                                        maxLines: 2,
                                                                                        style: TextStyle(fontFamily: 'Montserrat', fontSize: 10, color: Colors.black54),
                                                                                      ),
                                                                                    ),
                                                                                    Container(
                                                                                      padding: const EdgeInsets.only(bottom: 1.0),
                                                                                      child: _status != PermissionStatus.denied
                                                                                          ? snapshot.hasData
                                                                                              ? Text(
                                                                                                  snapshot.data + " " + "km",
                                                                                                  maxLines: 1,
                                                                                                  style: TextStyle(fontFamily: 'Montserrat', fontSize: 10, fontWeight: FontWeight.bold, color: colorBlue),
                                                                                                )
                                                                                              : SizedBox(
                                                                                                  child: CircularProgressIndicator(
                                                                                                    valueColor: new AlwaysStoppedAnimation<Color>(
                                                                                                      colorBlue,
                                                                                                    ),
                                                                                                    strokeWidth: 1,
                                                                                                  ),
                                                                                                  height: 5.0,
                                                                                                  width: 5.0,
                                                                                                )
                                                                                          : Icon(
                                                                                              Icons.do_not_disturb,
                                                                                              color: Colors.red,
                                                                                              size: 15,
                                                                                            ),                                                                                  ),
                                                                                    SizedBox(
                                                                                      height: 2,
                                                                                    ),
                                                                                    Container(
                                                                                                                                                                           child: Text(
                                                                                        _searchResult[position].price + " " + "USD",
                                                                                        style: TextStyle(
                                                                                          color: colorPink,
                                                                                          fontWeight: FontWeight.bold,
                                                                                          fontSize: 12,
                                                                                          fontFamily: 'Montserrat',
                                                                                        ),
                                                                                      ),
                                                                                    )
                                                                                  ],
                                                                                  crossAxisAlignment: CrossAxisAlignment.start,
                                                                                ),
                                                                                flex: 9,
                                                                              ),
                                                                              Column(
                                                                                children: <Widget>[
                                                                                  Container(
                                                                                      padding: const EdgeInsets.only(bottom: 0),
                                                                                      child: SmoothStarRating(
                                                                                          allowHalfRating: false,
                                                                                          onRatingChanged: (v) {
                                                                                            setState(() {});
                                                                                          },
                                                                                          starCount: 5,
                                                                                          rating: myrate,
                                                                                          size: 12.0,
                                                                                          filledIconData: Icons.star,
                                                                                          halfFilledIconData: Icons.star_half,
                                                                                          color: Colors.orange,
                                                                                          borderColor: Colors.orange,
                                                                                          spacing: 0.0)),
                                                                                  Text(
                                                                                    "(" + myrate.toStringAsFixed(1) + ")",
                                                                                    style: TextStyle(color: Colors.black, fontFamily: 'Montserrat', fontSize: 10, fontWeight: FontWeight.bold, fontStyle: FontStyle.normal),
                                                                                  ),
                                                                                ],
                                                                              )
                                                                            ],
                                                                          ),
                                                                        )
                                                                      ],
                                                                    )));
                                                      });
                                                }))

])

)

在上面的代码中,listview 从 json rest API.

获取数据

您可以将 3 个内部容器添加为列表视图的 children。

像这样:

Widget getListView(yourListWithData) {
    List<Widget> listViewChildren = [
      Container(),
      Container(),
      Container(),
    ];
    listViewChildren.addAll(
      yourListWithData
          .map(
            (e) => Text(e), //text widget as an example, use your own widget
          )
          .toList(),
    );

    return ListView(
      children: listViewChildren,
    );
  }

然后你可以摆脱 Column 并使列表视图成为 parent 容器的唯一 child:

 Container(
      child: getListView(yourListWithData),
    );

要解决这个问题:

  • physics: ClampingScrollPhysics() 属性的开头添加 SingleChildScrollView 小部件 .

  • shrinkWrap: true 属性添加到您的列表视图。

    SingleChildScrollView(
    scrollDirection: Axis.vertical,
    physics: ClampingScrollPhysics(),
    child: Container(
    child: Column( crossAxisAlignment: CrossAxisAlignment.start,
    children: <Widget>[
    
    Container(),
    
    Container(),
    
    Container(),
    
    Expanded(child: Listview.builder(shrinkWrap: true,))
    
    ])
    
    )
    

希望能帮到你

经过几个月的研究,我终于能够通过给出每个容器的高度来解决这个问题。由于我希望列表视图的高度覆盖 activity 中的大部分 space 我没有使用 ListView 设置容器的高度。首先我把上面的Expanded()改成Container(),设置ListViewshrinkWrap: true, physics: const NeverScrollableScrollPhysics(), 。在下面找到我更新的代码:


body: Container(
        child: Column(children: <Widget>[

Container(height: MediaQuery.of(context).size.height * 0.16,
          ),

Container(height: MediaQuery.of(context).size.height * 0.16,
          ),

Container(height: MediaQuery.of(context).size.height * 0.16,
                      ),

Container(child: ListView.separated(shrinkWrap: true,
              physics: const NeverScrollableScrollPhysics(),
              
                                                separatorBuilder:
                                                    (context, index) => Divider(
                                                          color: Colors.grey,
                                                        ),
                                                
                                                itemCount: content == null
                                                    ? 0
                                                    : _searchResult.length,
                                                itemBuilder:
                                                    (context, position) {
                                                  final current =
                                                      _searchResult[position];
                                                  double myrate = double.parse(
                                                      _searchResult[position]
                                                                  .ratings ==
                                                              null
                                                          ? "0"
                                                          : _searchResult[position]
                                                              .ratings);
                                                  debugPrint("rato:$myrate");
                                                  return FutureBuilder<String>(
                                                      future: getDistance(
                                                              current.lat,
                                                              current.lng)
                                                          .then((value) =>
                                                              value.toString()),
                                                      builder:
                                                          (context, snapshot) {
                                                        return Container(
                                                           
                                                            child:
                                                                GestureDetector(
                                                                    onTap: () {
                                                                      Navigator.push(
                                                                          context,
                                                                          CupertinoPageRoute(
                                                                              builder: (BuildContext ctx) => Maps(_searchResult[position])));
                                                                    },
                                                                    child:
                                                                        Column(
                                                                      children: <
                                                                          Widget>[
                                                                        Row(
                                                                          children: <
                                                                              Widget>[
                                                                            Expanded(
                                                                                child:Container(
                                                                                  height:150,
                                                                                  width: MediaQuery.of(context).size.width,

                                                                                  child: SizedBox(
                                                                                    child: FadeInImage(image: NetworkImage(_searchResult[position].thumbnail_name), placeholder: AssetImage("assets/640x360.png"),
                                                                                      fit: BoxFit.cover,),
                                                                                  ),
                                                                                )),
                                                                          ],
                                                                        ), 

                                                                        Container(
                                                                          padding:
                                                                              const EdgeInsets.all(5.0),
                                                                          child:
                                                                              Row(
                                                                            crossAxisAlignment:
                                                                                CrossAxisAlignment.start,
                                                                            children: <Widget>[
                                                                              Expanded(
                                                                                child: Column(
                                                                                  children: <Widget>[
                                                                                    Container(
                                                                                      padding: const EdgeInsets.only(bottom: 1.0),
                                                                                      child: Text(
                                                                                        _searchResult[position].title,
                                                                                        style: TextStyle(fontFamily: 'Montserrat', fontSize: 13, fontWeight: FontWeight.bold),
                                                                                      ),
                                                                                    ),
                                                                                    Container(
                                                                                      padding: const EdgeInsets.only(bottom: 1.0),
                                                                                      child: Text(
                                                                                        _searchResult[position].address,
                                                                                        maxLines: 2,
                                                                                        style: TextStyle(fontFamily: 'Montserrat', fontSize: 10, color: Colors.black54),
                                                                                      ),
                                                                                    ),
                                                                                    Container(
                                                                                      padding: const EdgeInsets.only(bottom: 1.0),
                                                                                      child: _status != PermissionStatus.denied
                                                                                          ? snapshot.hasData
                                                                                              ? Text(
                                                                                                  snapshot.data + " " + "km",
                                                                                                  maxLines: 1,
                                                                                                  style: TextStyle(fontFamily: 'Montserrat', fontSize: 10, fontWeight: FontWeight.bold, color: colorBlue),
                                                                                                )
                                                                                              : SizedBox(
                                                                                                  child: CircularProgressIndicator(
                                                                                                    valueColor: new AlwaysStoppedAnimation<Color>(
                                                                                                      colorBlue,
                                                                                                    ),
                                                                                                    strokeWidth: 1,
                                                                                                  ),
                                                                                                  height: 5.0,
                                                                                                  width: 5.0,
                                                                                                )
                                                                                          : Icon(
                                                                                              Icons.do_not_disturb,
                                                                                              color: Colors.red,
                                                                                              size: 15,
                                                                                            ),                                                                                  ),
                                                                                    SizedBox(
                                                                                      height: 2,
                                                                                    ),
                                                                                    Container(
                                                                                                                                                                           child: Text(
                                                                                        _searchResult[position].price + " " + "USD",
                                                                                        style: TextStyle(
                                                                                          color: colorPink,
                                                                                          fontWeight: FontWeight.bold,
                                                                                          fontSize: 12,
                                                                                          fontFamily: 'Montserrat',
                                                                                        ),
                                                                                      ),
                                                                                    )
                                                                                  ],
                                                                                  crossAxisAlignment: CrossAxisAlignment.start,
                                                                                ),
                                                                                flex: 9,
                                                                              ),
                                                                              Column(
                                                                                children: <Widget>[
                                                                                  Container(
                                                                                      padding: const EdgeInsets.only(bottom: 0),
                                                                                      child: SmoothStarRating(
                                                                                          allowHalfRating: false,
                                                                                          onRatingChanged: (v) {
                                                                                            setState(() {});
                                                                                          },
                                                                                          starCount: 5,
                                                                                          rating: myrate,
                                                                                          size: 12.0,
                                                                                          filledIconData: Icons.star,
                                                                                          halfFilledIconData: Icons.star_half,
                                                                                          color: Colors.orange,
                                                                                          borderColor: Colors.orange,
                                                                                          spacing: 0.0)),
                                                                                  Text(
                                                                                    "(" + myrate.toStringAsFixed(1) + ")",
                                                                                    style: TextStyle(color: Colors.black, fontFamily: 'Montserrat', fontSize: 10, fontWeight: FontWeight.bold, fontStyle: FontStyle.normal),
                                                                                  ),
                                                                                ],
                                                                              )
                                                                            ],
                                                                          ),
                                                                        )
                                                                      ],
                                                                    )));
                                                      });
                                                }))

])

)