颤振 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 的无限滚动的主要内容,如果未能解决你的问题,请参考以下文章

如何使用颤振使列表视图滚动 360

在 Flutter 中创建一个双向无限 ListView.builder

当您一直滚动到 ListView.builder 的顶部时,如何禁用动画

颤振中的 LIstView.builder

颤振 ListView.builder 使 onPressed 仅适用于关注项

如何从http POST请求结果颤振在listview builder上显示数据