简体   繁体   中英

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

I have a container with a column that have three containers and one listview wrapped with expanded which works perfectly but am trying to add a scrollview to the whole container so that on the three scroll with the listview, please how can I achieve this? Below is what my code looks like.


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),
                                                                                  ),
                                                                                ],
                                                                              )
                                                                            ],
                                                                          ),
                                                                        )
                                                                      ],
                                                                    )));
                                                      });
                                                }))

])

)

In the above code the listview fetch it data from json rest API.

So finally after many months of research, I was able to resolve this by giving the height of each container. Since I want the height of the listview to cover most of the space in the activity I didn't set the height for the Container with the ListView. First I changed the Expanded() above to Container() , set ListView shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), . Find below my updated code:


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),
                                                                                  ),
                                                                                ],
                                                                              )
                                                                            ],
                                                                          ),
                                                                        )
                                                                      ],
                                                                    )));
                                                      });
                                                }))

])

)




You could add the 3 inner containers as children of the listview.

Something like this:

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

And then you can get rid of the Column and make the listview the only child of the parent container:

 Container(
      child: getListView(yourListWithData),
    );

To solve that:

  • Add SingleChildScrollView Widget at the beginning with physics: ClampingScrollPhysics() propertie.

  • Add shrinkWrap: true propertie to your Listview.

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

I hope to help you

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM