Flutter ListView 不滚动到最后一个元素

时间:2021-03-16 15:13:40

标签: flutter android-listview

我在 PageView 中的 listview 有问题,当我滚动到底部时,缺少两行。

我可以通过更新 ListView 所在容器的高度来纠正这个问题,但屏幕渲染并未针对所有屏幕尺寸进行优化。

Screenshot of the match results list

我们可以成功滚动 8 或 150 个匹配项,当我们完成滚动操作时,我们总是会错过最后 2 个匹配项。

这里是管理页面浏览的代码:

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

这是结果小部件的代码:

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

1 个答案:

答案 0 :(得分:0)

我认为 ListView.builder 中嵌套的 ListView 可能是问题所在。

在下面的示例中,我试图复制您的小部件树,如果没有内部 physics: ClampingScrollPhysics() 上的 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 ;)

相关问题