Flutter ListView没有滚动到最后一个元素
Posted
技术标签:
【中文标题】Flutter ListView没有滚动到最后一个元素【英文标题】:Flutter ListView not scrolling to last element 【发布时间】:2021-06-13 21:40:53 【问题描述】:PageView 中的 listview 有问题,当我滚动到底部时,缺少两行。
我可以通过更新 ListView 所在的 Container 的高度来纠正这个问题,但屏幕渲染并未针对所有屏幕尺寸进行优化。
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】:我认为ListView
中的嵌套ListView.builder
可能是问题所在。
在下面的示例中,我尝试复制您的小部件树,如果没有内部ListView.builder
上的physics: ClampingScrollPhysics()
,我根本无法滚动结果列表。
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 ;)
【讨论】:
谢谢!我使用了您的代码,并用我的 Padding 小部件替换了您的 ListTile,它解决了我的问题以上是关于Flutter ListView没有滚动到最后一个元素的主要内容,如果未能解决你的问题,请参考以下文章
在 Flutter 应用程序中的 ListView 滚动上隐藏/关闭键盘