颤振 ListView.builder 的无限滚动
Posted
技术标签:
【中文标题】颤振 ListView.builder 的无限滚动【英文标题】:flutter Infinite Scrolling for ListView.builder 【发布时间】:2021-12-22 03:45:43 【问题描述】:我必须使用 graphql 查询,并且我已经逐页获取数据。 所以我需要在我的列表视图构建器中无限滚动,但我不知道如何在页面中添加 num。 谁能帮帮我?
这是我的查询:
query homeview(\$moreId: ID!, \$page: Int! )
homeview(HM_ID: \$moreId, page: \$page)
HM_ID
HM_Type_ID
HM_Type_Name
""";
这是我在page
中传递整数的变量:
dynamic pageNum = 0;
这里是控制器:
ScrollController _scrollController = new ScrollController( initialScrollOffset: 10,
这是我的列表视图生成器:
class MoreEpd extends StatefulWidget
final String moreId;
const MoreEpd(Key? key, required this.moreId) : super(key: key);
@override
_MoreEpdState createState() => _MoreEpdState();
class _MoreEpdState extends State<MoreEpd>
double pageWidth = 0;
double pageHeigh = 0;
dynamic pageNum = 0;
final String leftArrow = 'assets/icons/left-arrow.svg';
String getSearchResult = """
query homeview(\$moreId: ID!, \$page: Int! )
homeview(HM_ID: \$moreId, page: \$page)
HM_ID
Priority
Details
Ep_ID
Image
title
Pod_title
""";
@override
Widget build(BuildContext context)
pageWidth = MediaQuery.of(context).size.width;
pageHeigh = MediaQuery.of(context).size.height;
return Container(
child: Query(
options: QueryOptions(
document: gql(getSearchResult),
variables: 'moreId': widget.moreId, 'page': pageNum,
),
builder: (
QueryResult result,
Refetch? refetch,
FetchMore? fetchMore,
)
return handleResult(result);
,
),
);
Widget handleResult(QueryResult result)
var data = result.data!['homeview']['Details'] ?? [];
return Container(
child: ListView.builder(
padding: EdgeInsets.only(top: 15),
shrinkWrap: true,
itemCount: data.length ,
itemBuilder: (context, index)
return InkWell(
onTap: () ,
child: Padding(
padding: EdgeInsets.only(
top: pageWidth * 0.0,
right: pageWidth * 0.08,
left: pageWidth * 0.08,
bottom: pageWidth * 0.0),
child: Container(
child: Stack(
children: [
Column(
children: [
Padding(
padding:
EdgeInsets.only(bottom: pageWidth * 0.060),
child: Row(
children: [
Padding(
padding:
EdgeInsets.only(left: pageWidth * 0.01),
child: Container(
// alignment: Alignment.centerRight,
width: pageWidth * 0.128,
height: pageWidth * 0.128,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: CachedNetworkImageProvider(
data[index]['Image'],
)),
borderRadius: BorderRadius.all(
Radius.circular(15)),
// color: Colors.redAccent,
border: Border.all(
color: MyColors.lightGrey,
width: 1,
)),
),
),
Expanded(
child: Row(
children: [
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Container(
width: pageWidth * 0.5,
alignment: Alignment.centerRight,
child: Text(
data[index]['title'],
textAlign: TextAlign.right,
overflow: TextOverflow.ellipsis,
maxLines: 1,
// softWrap: true,
style: TextStyle(
// fontWeight: FontWeight.bold,
fontSize: 14,
),
),
),
],
),
],
),
)
],
),
),
],
),
],
),
),
),
);
));
谁能帮助我,请问如何使用无限滚动在我的查询中加载其他页面?
【问题讨论】:
为什么需要无限滚动? listview.builder 将尽可能大,以适应所有数据 因为我应该将 int num 传递给page
查询并从中获取数据。
【参考方案1】:
最简单的方法是使用ListView.builder
而不指定itemCount
参数。
这是最简单的例子:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return new MaterialApp(
home: new MyHomePage(),
);
class MyHomePage extends StatefulWidget
@override
_MyHomePageState createState() => new _MyHomePageState();
class _MyHomePageState extends State<MyHomePage>
@override
Widget build(BuildContext context)
return new Scaffold(
appBar: new AppBar(
title: new Text("Infinite List"),
),
body: ListView.builder(
itemBuilder: (context, index)
return Text("$index");
,
),
);
稍后,您可以通过获取真实数据来增强此功能。您可以在等待新数据时在列表的最后一项中显示“CircularProgressIndicator”。
body: ListView.builder(
itemBuilder: (context, index)
if (index < data.length)
// Show your info
return Text("$index");
else
getMoreData();
return Center(child: CircularProgressIndicator());
,
itemCount: data.length + 1,
),
您可以看到我们通过添加索引来欺骗列表,并在显示最终索引时调用更多数据。
getMoreData()
将包括对setState()
的调用以强制重建并考虑新数据。
【讨论】:
什么是 getMoreData()?类还是方法? 我不知道应该在 getMoreData 中放什么。我只想pageNum +=1;
这发生并加载更多数据
@stysh 它是函数 _getMoreData() async final moreItems = await widget.onRequest(items.length);如果 (!mounted) 返回; if (moreItems.isEmpty) setState(() => end = true);返回; setState(() => items = [...items, ...moreItems]);
@stysh 你也可以查看本教程dartpad.dev/…。如果有帮助,请点赞
@lnfostans 这很酷,但我无法将它与我的项目相匹配。我上传有问题的课程。请您看看并告诉我该怎么做?以上是关于颤振 ListView.builder 的无限滚动的主要内容,如果未能解决你的问题,请参考以下文章
在 Flutter 中创建一个双向无限 ListView.builder
当您一直滚动到 ListView.builder 的顶部时,如何禁用动画