当我们接近底部 [FLUTTER] 时,如何实现无限滚动?

问题描述

当我使用以下代码时,我可以在到达列表视图底部获取新数据

  controller.addListener(() {
    if(controller.position.pixels==controller.position.maxScrollExtent){
      postController.fetchNewPosts(postController.postList.last.timeupdated);
    }
  });

但我不想在我到达底部获取它们,而是在我接近它时获取它们,以便用户在到达底部时不会等待。

child: Obx(() => NotificationListener<ScrollNotification>(
      onNotification: (ScrollNotification notification){
        if(notification.metrics.maxScrollExtent > notification.metrics.pixels &&
            notification.metrics.maxScrollExtent - notification.metrics.pixels <=
                60.0){
          print(postController.postList.last.post);
          postController.fetchNewPosts(postController.postList.last.timeupdated);
          print('DENEME');
        }
        return false;
      },child: ListView.builder(
          controller: controller,itemCount: postController.postList.length,itemBuilder: (context,index) {
            return Card(
              child: Row(

当我使用此代码时,它会在一秒钟内触发该函数 15 次... 我怎样才能正确地做到这一点?

解决方法

您不需要像这样的 NotificationListener,因为它在构建时一直在执行。

尝试添加一个 ScrollController

final ScrollController scrollController = ScrollController();

然后添加滚动监听器方法

void _scrollListener() {
    if (scrollController.offset >= scrollController.position.maxScrollExtent &&
        !scrollController.position.outOfRange) {
       print(postController.postList.last.post);
      postController.fetchNewPosts(postController.postList.last.timeupdated);
      print('DENEME');
      }
    }
  }

并在 initState 中将此侦听器添加到滚动控制器

@override
  void initState() {
    scrollController.addListener(_scrollListener);
    super.initState();
  }
,

改为:

  controller.addListener(() {
    if(controller.position.pixels==controller.position.maxScrollExtent-200){
      postController.fetchNewPosts(postController.postList.last.timeupdated);
    }
  });

200 是到达底部之前的距离,设置你喜欢的任何值

,

我使用 https://pub.dev/packages/inview_notifier_list 这个库来实现。 在低层设备中,它可能会导致性能问题。像卡顿,帧问题。

这里是示例。 希望能帮到你。

SafeArea(
      child: Stack(
        children: [
          InViewNotifierCustomScrollView(
            physics: Platform.isAndroid ? ClampingScrollPhysics() : RangeMaintainingScrollPhysics(),isInViewPortCondition: widget.inViewPortCondition ??
                    (double deltaTop,double deltaBottom,double vpHeight) {
                  return deltaTop < (0.7 * vpHeight) && deltaBottom > (0.7 * vpHeight);
                },endNotificationOffset: mw(500),onListEndReached: () async{
              if(_list1.length == _totCnt) {
                setState(() {
                  _noMoreItem = 'No more Models';
                });
              } else {
                if(_moreItems) {
                  setState(() {
                    _isLoad = true;
                    _moreItems = false;
                    _offset = _offset + 30;
                  });
                  bool _rrr = await getModelList($user.accessToken,$user.appInfo);
                  if(_rrr) {
                    setState(() {
                      _moreItems = true;
                    });
                  }
                } else {
                }
              }
            },controller: _bscrollController,slivers: [
              SliverAppBar(
                automaticallyImplyLeading: false,elevation: 0,brightness: Brightness.light,title: Text('Models',style: Ts.h15bb(),),actions: [
                  GestureDetector(
                      behavior: HitTestBehavior.translucent,onTap: () {
                        Navigator.push(context,MaterialPageRoute(builder: (context) => SearchPage()));
                      },child: Icon(Icons.search,size: mw(26),)),SizedBox(width: mw(10),GestureDetector(
                      behavior: HitTestBehavior.translucent,MaterialPageRoute(builder: (context) => CartPage()));
                      },child:  Stack(
                        children: [
                          Padding(
                            padding: EdgeInsets.only(top: mw(13),right: mw(18)),child: Image.asset('assets/pickling_cart.png',width: mw(18),height: mw(22),$user.cartCnt == '0' ? Container():Positioned(
                              top: mw(9),right: mw(10),child: ClipRRect(
                                borderRadius: BorderRadius.all(Radius.circular(10)),child: Container(
                                  height: mw(16),padding: EdgeInsets.only(left: mw(5),right: mw(5),bottom: mw(2)),color: Colors.black,child: Center(child: Text('${$user.cartCnt}',style: Ts.ctwb(),)
                          )
                        ],],_totCnt == 0 ?
              SliverToBoxAdapter(
                child: Padding(
                  padding: EdgeInsets.only(top:mw(50)),child:
                  Center(
                      child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,crossAxisAlignment: CrossAxisAlignment.center,children: [
                      Text('There are no models!',style: Ts.h3bb()),SizedBox(height:mw(5)),Text(':X',style: Ts.bd1gm(),))
                ),):
              SliverPadding(
                padding: EdgeInsets.only(top: mw(2)),sliver: SliverList(
                  delegate: SliverChildBuilderDelegate(
                    (BuildContext context,int index) {
                      return Column(
                        children: [
                          ModelItem(imgURL,index,$user),Divider(thickness: 1,color: Du.lightGrey(),)
                        ],);
                    },childCount: _list1.length
                  )
                )
              )

            ],)
    );

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...