peng8350 / flutter_pulltorefresh

a widget provided to the flutter scroll component drop-down refresh and pull up load.
MIT License
2.71k stars 722 forks source link

第一屏列表没满时,底部的没有更多数据,会出现下拉刷新一次消失,再刷新一次又出现,再刷新一次又消失 #414

Closed bravecheng closed 3 years ago

bravecheng commented 3 years ago

问题

第一屏列表没满时,底部的没有更多数据,会出现下拉刷新一次消失,再刷新一次又出现,再刷新一次又消失。

配置信息

  ///配置下拉刷新
  Widget _refreshConfiguration() {
    return RefreshConfiguration(
      headerBuilder: () => WaterDropHeader(),   // 配置默认头部指示器
      footerBuilder:  () => ClassicFooter(),    // 配置默认底部指示器
      headerTriggerDistance: 40.pt,             // 头部触发刷新的越界距离
      maxOverScrollExtent :50.pt,               // 头部最大可以拖动的范围
      maxUnderScrollExtent:0,                   // 底部最大可以拖动的范围
      enableScrollWhenRefreshCompleted: true,   // 需要TabBarView左右滑动,设置为true
      enableLoadingWhenFailed : true,           // 在加载失败的状态下,用户仍然可以通过手势上拉来触发加载更多
      hideFooterWhenNotFull: true,              // 不满一屏时,禁用上拉加载更多功能
      enableBallisticLoad: true,                // 可以通过惯性滑动触发加载更多
      child: MaterialApp(
        title: '',
        debugShowCheckedModeBanner: false,      // 配置关闭debug角标
        themeMode: Util.themeMode,              // 配置主题模式
        theme: lightTheme,                      // 配置日间模式
        darkTheme: darkTheme,                   // 配置暗黑模式
        onGenerateRoute: router.generator,      // 配置路由
        builder: (BuildContext context, Widget child) {
          return Directionality(
            textDirection: Util.textDirection,
            child: child,
          );
        },
        locale: const Locale('zh'),
        supportedLocales: [
          const Locale('zh'),
        ],
        localizationsDelegates: [
          RefreshLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
          GlobalMaterialLocalizations.delegate,
          GlobalCupertinoLocalizations.delegate,
        ],
      ),
    );
  }

ListView布局代码

import 'package:flutter/material.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import '../models/realtime_info.dart';
import '../utils/event_bus.dart';
import '../utils/size_extension.dart';
import '../utils/vehicle_manager.dart';

class ListViewPage extends StatefulWidget {
  @override
  State<ListViewPage> createState() => ListViewPageState();
}

class ListViewPageState extends State<ListViewPage> {
  var _begin = 0;
  var _groupId;
  var _items = List<Realtimeinfo>();
  var _refreshController = RefreshController(initialRefresh: true);

  @override
  void initState() {
    super.initState();
    //注册车辆信息获取成功监听
    eventBus.on<RealtimeinfoSuccessEvent>().listen((event) {
      //下标赋值
      _begin = event.begin;
      //第一页数据,清空之前的列表
      if (event.begin == 0) {
        _items.clear();
      }
      //添加数据
      _items.addAll(event.realtimeInfos);
      //刷新界面
      if (mounted) setState(() {});
      //如果在刷新
      if (_refreshController.isRefresh) {
        _refreshController.refreshCompleted();
      }
      //如果在加载更多
      if (_refreshController.isLoading) {
        //数据加载
        _refreshController.loadComplete();
      }
      if (!(event.end < event.total)) {
        //如果没有数据或者数据加载完毕
        _refreshController.loadNoData();
      }
    });
    //注册车辆信息获取失败监听
    eventBus.on<RealtimeinfoFailedEvent>().listen((event) {
      //如果在刷新
      if (_refreshController.isRefresh) {
        _refreshController.refreshFailed();
      }
      //如果在加载更多
      if (_refreshController.isLoading) {
        //数据加载
        _refreshController.loadFailed();
      }
    });
  }

  void _onRefresh() {
    eventBus.fire(RealtimeinfoRequestEvent(0, _groupId));
  }

  void _onLoading() {
    eventBus.fire(RealtimeinfoRequestEvent(_begin + RealtimeinfoRequestEvent.defaultLimit, _groupId));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SmartRefresher(
        enablePullDown: true,
        enablePullUp: true,
        controller: _refreshController,
        onRefresh: _onRefresh,
        onLoading: _onLoading,
        child: ListView.builder(
          itemBuilder: (context, index) => _itemView(index, _items[index]),
          itemExtent: 90.pt,
          itemCount: _items.length,
        ),
      ),
    );
  }

  Widget _itemView(int index, Realtimeinfo info) {
    return Container(
      margin: EdgeInsets.only(top: 7.pt, left: 15.pt, right: 15.pt),
      decoration: BoxDecoration(
        color: Theme.of(context).cardColor,
        borderRadius: BorderRadius.circular(8.pt),
        boxShadow: [
          BoxShadow(
            color: Colors.black12,
            offset: Offset(0, 0), //阴影xy轴偏移量
            blurRadius: 3.pt, //阴影模糊程度
            spreadRadius: 1.pt, //阴影扩散程度
          )
        ],
      ),
      child: Stack(
        alignment: Alignment.centerLeft,
        children: [
          Positioned(
            left: 10.pt,
            top: 10.pt,
            width: 30.pt,
            height: 30.pt,
            child: vehicleManager.getVehicleIcon(info, width: 30.pt, height: 30.pt),
          ),
          Positioned(
            left: 50.pt,
            bottom: 52.pt,
            child: Text(info.licence, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16.pt)),
          ),
          Positioned(
            left: 50.pt,
            child: Text(vehicleManager.getFormatTime(info.dtime), style: TextStyle(fontSize: 14.pt)),
          ),
          Positioned(
            left: 50.pt,
            top: 52.pt,
            right: 10.pt,
            child: Text(info.descsummary.replaceAll("[]", ""), style: TextStyle(fontSize: 14.pt), maxLines: 1),
          ),
          Positioned(
            right: 10.pt,
            bottom: 55.pt,
            child: Row(
              children: [
                vehicleManager.getGpsIcon(info),
                SizedBox(width: 6.pt),
                vehicleManager.getOnlineIcon(info),
                SizedBox(width: 6.pt),
                vehicleManager.getStopIcon(info),
                SizedBox(width: 6.pt),
                vehicleManager.getBatteryIcon(info),
                SizedBox(width: 6.pt),
                vehicleManager.getAlarmIcon(info),
                SizedBox(width: 6.pt),
                vehicleManager.getControlIcon(info),
                SizedBox(width: 6.pt),
                vehicleManager.getServerIcon(info),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
bravecheng commented 3 years ago

找到原因了, _controller.loadComplete() 和 _controller.loadNoData() 不能同时调用,只能调用一次,不然就会出现上面的原因。

gersces commented 3 years ago

我也有此问题,我并没有将“_controller.loadComplete() 和 _controller.loadNoData() 同时调用”,我是将 _controller.refreshCompleted() 和 _controller.loadNoData() 同时调用了。 1621914187883