简体   繁体   中英

Flutter ListView not scrolling to last element

I have a problem with listview inside PageView, when i scroll to the bottom, two rows are missing.

I can correct that by updating the height of the Container where the ListView is located but the screen rendering is not optimized for all the screen sizes.

Screenshot of the match results list

We can scroll 8 or 150 matches successfully, we will always miss the last 2 matches when we finish the scrolling action.

Here is the code where the pageview is managed:

class Results extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
        fontFamily: "Josefin",
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: HomeResults(),
    );
  }
}

class HomeResults extends StatefulWidget {
  @override
  _HomeResultsState createState() => _HomeResultsState();
}

class _HomeResultsState extends State<HomeResults> {
  PageController _controller = PageController(
    initialPage: 0,
  );

  int currentPage = 0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        child: Column(
          children: [
            Container(
              height: 45,
              child: ListView.builder(
                shrinkWrap: true,
                itemBuilder: (ctx, i) {
                  return Container(
                    child: FlatButton(
                      onPressed: () {
                        _controller.animateToPage(i,
                            duration: Duration(milliseconds: 300),
                            curve: Curves.easeIn);
                      },
                      child: Text(
                        resultscateg[i],
                        style: TextStyle(
                          color: currentPage == i
                              ? Colors.black
                              : Colors.black.withOpacity(0.4),
                        ),
                      ),
                    ),
                  );
                },
                itemCount: resultscateg.length,
                scrollDirection: Axis.horizontal,
              ),
            ),
            Expanded(
              child: PageView(
                controller: _controller,
                onPageChanged: (value) {
                  setState(() {
                    currentPage = value;
                  });
                },
                children: [
                  FutureBuilder<List<Match>>(
                    future: MatchRepository().getResults(1),
                    builder: (context, snapshot) {
                      if (snapshot.hasError) print(snapshot.error);

                      return snapshot.hasData
                          ? ResultsWidget(resultsList: snapshot.data)
                          : Center(
                              child: CircularProgressIndicator(
                              valueColor:
                                  new AlwaysStoppedAnimation<Color>(Colors.red),
                            ));
                    },
                  ),
                  FutureBuilder<List<Match>>(
                    future: MatchRepository().getResults(2),
                    builder: (context, snapshot) {
                      if (snapshot.hasError) print(snapshot.error);

                      return snapshot.hasData
                          ? ResultsWidget(resultsList: snapshot.data)
                          : Center(
                              child: CircularProgressIndicator(
                              valueColor:
                                  new AlwaysStoppedAnimation<Color>(Colors.red),
                            ));
                    },
                  ),
                ],
              ),
            )
          ],
        ),
      ),
    );
  }
}

And here is the code of the results widget:

class ResultsWidget extends StatelessWidget {
  final List<Match> resultsList;

  ResultsWidget({Key key, this.resultsList}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Container(
          width: MediaQuery.of(context).size.width,
          child: ListView(
            children: [
              //last results
              Container(
                // Pour gérer le padding entre les scores
                height: MediaQuery.of(context).size.height,
                child: resultsList.isEmpty
                    ? Center(child: Text('Aucun résultat actuellement.'))
                    : ListView.builder(
                        itemCount: resultsList.length,
                        scrollDirection: Axis.vertical,
                        shrinkWrap: true,
                        itemBuilder: (ctx, i) => Padding(
                          padding: EdgeInsets.all(10),
                          child: Material(
                            color: Colors.white,
                            elevation: 5,
                            borderRadius: BorderRadius.circular(15),
                            clipBehavior: Clip.hardEdge,
                            child: Container(
                              width: MediaQuery.of(context).size.width,
                              height: 110,
                              padding: EdgeInsets.all(5),
                              child: Column(
                                mainAxisAlignment:
                                    MainAxisAlignment.spaceAround,
                                children: <Widget>[
                                  Container(
                                    height: 30,
                                    decoration: BoxDecoration(
                                      image: DecorationImage(
                                          image: AssetImage(
                                              "assets/images/bgheader.png"),
                                          fit: BoxFit.cover),
                                      // Gère l'arrondi des bords de chaque score
                                      borderRadius: BorderRadius.circular(10),
                                    ),
                                    child: Row(
                                      children: [
                                        Expanded(
                                          child: Padding(
                                            padding: const EdgeInsets.all(6.0),
                                            child: Text(
                                                resultsList[i]
                                                        .etapecompetition
                                                        .libelle ??
                                                    "",
                                                maxLines: 1,
                                                textAlign: TextAlign.left,
                                                overflow: TextOverflow.fade,
                                                style: TextStyle(
                                                    fontSize: 14,
                                                    fontWeight: FontWeight.bold,
                                                    color: Colors.yellow)),
                                          ),
                                        ),
                                        Expanded(
                                          child: Padding(
                                            padding: const EdgeInsets.all(6.0),
                                            child: Text(
                                                resultsList[i].roundLibelle ??
                                                    "",
                                                maxLines: 1,
                                                textAlign: TextAlign.right,
                                                overflow: TextOverflow.fade,
                                                style: TextStyle(
                                                    fontSize: 14,
                                                    color: Colors.white)),
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                                  Row(
                                    mainAxisAlignment:
                                        MainAxisAlignment.spaceEvenly,
                                    children: <Widget>[
                                      Container(
                                        height: 50,
                                        width: 50,
                                        decoration: BoxDecoration(
                                          shape: BoxShape.circle,
                                        ),
                                        child: ClipRRect(
                                          borderRadius:
                                              BorderRadius.circular(10),
                                          child: Image.network(
                                            'https://ruiznicolas.ovh/img/logos/${resultsList[i].equipe1.logo ?? "asa.png"}',
                                            height: 95,
                                            fit: BoxFit.fitHeight,
                                          ),
                                        ),
                                      ),
                                      SizedBox(
                                        //Marge du logo de gauche par rapport au reste
                                        width: 5,
                                      ),
                                      Expanded(
                                        //Colonne de l'equipe 1
                                        child: Column(
                                          //Gère le centrage du texte
                                          mainAxisAlignment:
                                              MainAxisAlignment.spaceEvenly,
                                          crossAxisAlignment:
                                              CrossAxisAlignment.start,
                                          children: [
                                            Text(
                                              '',
                                              style: TextStyle(
                                                color: Colors.white,
                                              ),
                                            ),
                                            Text(
                                              resultsList[i].equipe1.nom ?? "",
                                              maxLines: 2,
                                              overflow: TextOverflow.fade,
                                              style: TextStyle(
                                                color: Colors.black,
                                                fontSize: 17,
                                                fontWeight: FontWeight.bold,
                                              ),
                                            ),
                                            Text(
                                              "",
                                              style: TextStyle(
                                                color: Colors.white
                                                    .withOpacity(0.7),
                                              ),
                                            )
                                          ],
                                        ),
                                      ),
                                      Expanded(
                                        //Colonne du score
                                        child: Column(
                                          //Gère le centrage du texte
                                          mainAxisAlignment:
                                              MainAxisAlignment.spaceEvenly,
                                          crossAxisAlignment:
                                              CrossAxisAlignment.center,
                                          children: [
                                            Text(
                                              '',
                                              style: TextStyle(
                                                color: Colors.white,
                                              ),
                                            ),
                                            Text(
                                              '${resultsList[i].score1 ?? ""} - ${resultsList[i].score2 ?? ""}',
                                              maxLines: 2,
                                              textAlign: TextAlign.center,
                                              overflow: TextOverflow.fade,
                                              style: TextStyle(
                                                color: Colors.grey,
                                                fontSize: 17,
                                                fontWeight: FontWeight.bold,
                                              ),
                                            ),
                                            resultsList[i].tabs1 != null
                                                ? Text(
                                                    "(TAB : ${resultsList[i].tabs1 ?? ""} - ${resultsList[i].tabs2 ?? ""})",
                                                    style: TextStyle(
                                                      color: Colors.grey
                                                          .withOpacity(0.7),
                                                      fontSize: 12,
                                                    ),
                                                  )
                                                : Text(
                                                    "",
                                                    style: TextStyle(
                                                      color: Colors.grey
                                                          .withOpacity(0.7),
                                                    ),
                                                  )
                                          ],
                                        ),
                                      ),
                                      Expanded(
                                        //Colonne de l'equipe 2
                                        child: Column(
                                          //Gère le centrage du texte
                                          mainAxisAlignment:
                                              MainAxisAlignment.spaceEvenly,
                                          crossAxisAlignment:
                                              CrossAxisAlignment.end,
                                          children: [
                                            Text(
                                              '',
                                              style: TextStyle(
                                                color: Colors.white,
                                              ),
                                            ),
                                            Text(
                                              resultsList[i].equipe2.nom ?? "",
                                              maxLines: 2,
                                              textAlign: TextAlign.center,
                                              overflow: TextOverflow.fade,
                                              style: TextStyle(
                                                color: Colors.black,
                                                fontSize: 17,
                                                fontWeight: FontWeight.bold,
                                              ),
                                            ),
                                            Text(
                                              "",
                                              style: TextStyle(
                                                color: Colors.white
                                                    .withOpacity(0.7),
                                              ),
                                            )
                                          ],
                                        ),
                                      ),
                                      Container(
                                        height: 50,
                                        width: 50,
                                        decoration: BoxDecoration(
                                          shape: BoxShape.circle,
                                        ),
                                        child: ClipRRect(
                                          borderRadius:
                                              BorderRadius.circular(10),
                                          child: Image.network(
                                            'https://ruiznicolas.ovh/img/logos/${resultsList[i].equipe2.logo ?? ""}',
                                            height: 95,
                                            fit: BoxFit.fitHeight,
                                          ),
                                        ),
                                      ),
                                      SizedBox(
                                        //Marge du logo de gauche par rapport au reste
                                        width: 5,
                                      ),
                                    ],
                                  )
                                ],
                              ),
                            ),
                          ),
                        ),
                      ),
              ),
            ],
          ),
        )
      ],
    );
  }
}

I think the nested ListView.builder inside a ListView might be the issue.

With the example below, where I tried to replicate your widget tree, I couldn't scroll the results list at all without physics: ClampingScrollPhysics() on the inner ListView.builder .

import 'package:flutter/material.dart';

class ListViewScrollastPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ListView Scrollast'),
      ),
      body: ResultsWidget(),
    );
  }
}

class ResultsData {
  List<int> results = List.generate(20, (index) => index + 1);
}

class ResultsWidget extends StatelessWidget {
  final List<int> results = List.generate(20, (index) => index + 1);

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Container(
          child: ListView(
            children: [
              Container(
                child: ListView.builder(
                  itemCount: results.length,
                  shrinkWrap: true,
                  // ************************************************************
                  physics: ClampingScrollPhysics(), // ← can't scroll nested list without
                  // ************************************************************
                  itemBuilder: (context, index) {
                    return ListTile(
                      title: Text('Match ${results[index]}'),
                      subtitle: Text('Win Draw Loss'),
                    );
                  },
                ),
              )
            ],
          ),
        )
      ],
    );
  }
}

J'espère que ça t'aide;)

SingleChildScrollView( reverse: true, child: ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: 100, itemBuilder: (context, index) => Text( index.toString(), ), ), )strong text

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