我在 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,
),
],
)
],
),
),
),
),
),
),
],
),
)
],
);
}
}
答案 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 ;)