Flutter 中 PageController 出现异常:“A PagingController was used after was Dispose”

问题描述 投票:0回答:1

Flutter 社区您好,

我在 Flutter 应用程序中遇到异常,该异常似乎与处置后使用的 PagingController 相关。但是,在我的实现中,我使用的是 PageController 而不是 PagingController。异常发生在调度程序回调期间,堆栈跟踪指向 PagingController。

这是我面临的例外:

════════ Exception caught by scheduler library ═════════════════════════════════
The following _Exception was thrown during a scheduler callback:
Exception: A PagingController was used after being disposed.
Once you have called dispose() on a PagingController, it can no longer be used.
If you’re using a Future, it probably completed after the disposal of the owning widget.
Make sure dispose() has not been called yet before using the PagingController.

When the exception was thrown, this was the stack:
#0      PagingController._debugAssertNotDisposed.<anonymous closure> (package:infinite_scroll_pagination/src/core/paging_controller.dart:133:9)
paging_controller.dart:133
#1      PagingController._debugAssertNotDisposed (package:infinite_scroll_pagination/src/core/paging_controller.dart:142:6)
paging_controller.dart:142
#2      PagingController.notifyPageRequestListeners (package:infinite_scroll_pagination/src/core/paging_controller.dart:203:12)
paging_controller.dart:203
#3      _PagedSliverBuilderState._buildListItemWidget.<anonymous closure> (package:infinite_scroll_pagination/src/ui/paged_sliver_builder.dart:255:29)
paged_sliver_builder.dart:255
#4      SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1325:15)
binding.dart:1325
#5      SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1264:9)
binding.dart:1264
#6      SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1113:5)
binding.dart:1113
#7      _invoke (dart:ui/hooks.dart:312:13)
hooks.dart:312
#8      PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:383:5)
platform_dispatcher.dart:383
#9      _drawFrame (dart:ui/hooks.dart:283:31)
hooks.dart:283
════════════════════════════════════════════════════════════════════════════════

在我的应用程序中,我确保在小部件的 dispose 方法中正确处置 PageController。这是我与 PageController 相关的代码片段:

import 'package:bework/src/components/app_bar_widget.dart';
import 'package:bework/src/screens/dashboard_screen.dart';
import 'package:bework/src/screens/project.dart';
import 'package:bework/src/screens/records_screen.dart';
import 'package:bework/src/screens/time_off_screen.dart';
import 'package:flutter/material.dart';
import 'package:nb_utils/nb_utils.dart';

class MWBottomNavigationScreen2 extends StatefulWidget {
  @override
  MWBottomNavigationScreen2State createState() => MWBottomNavigationScreen2State();
}

class MWBottomNavigationScreen2State extends State<MWBottomNavigationScreen2> {
  int isSelected = 0;
  bool pageControllerIsDisposed = false;
  late PageController pageController;

  @override
  void initState() {
    super.initState();
    print('Navigation Screen 1');
    pageController = PageController();
    print('Navigation Screen 2');
  }

  @override
  void setState(fn) {
    if (mounted) super.setState(fn);
  }

  @override
  void dispose() {
    print('Navigation Screen 3');
    pageControllerIsDisposed = true;
    pageController.dispose();
    print('Navigation Screen 4');
    super.dispose();
  }

  Widget tabItem(var pos, var icon) {
    return GestureDetector(
      onTap: () async {
        try {
          print('Navigation Screen 5');
        if (pageControllerIsDisposed) return;
        if (!mounted) return;

        setState(() {
          isSelected = pos;
           
        });
        await pageController.animateToPage(
              isSelected,
              duration: Duration(milliseconds: 300),
              curve: Curves.easeInOut,
            );
          print('Navigation Screen 6');
        } catch (e) {
            print('ERROR ANIMATING SCREEN');

            print(e);
          }
      },
      child: Padding(
        padding: EdgeInsets.all(0.0),
        child: Container(
          alignment: Alignment.center,
          decoration: isSelected == pos ? BoxDecoration(shape: BoxShape.rectangle, color: Color(0xffe4aa4c)) : BoxDecoration(),
          child: Image.asset(
            icon,
            width: 30,
            height: 30,
            color: isSelected == pos ? black : white,
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: CustomAppBar(),
      body: PageView(
        controller: pageController,
        onPageChanged: (index) {
          if (pageControllerIsDisposed) return;
          setState(() {
            isSelected = index;
          });
        },
        children: [
          Dashboard(name: 'John Doe'),
          ProjectTasks(),
          TimeOffScreen(),
          RecordsScreen(),
        ],
      ),
      bottomNavigationBar: Stack(
        alignment: Alignment.topCenter,
        children: <Widget>[
          Container(
            height: 60,
            decoration: BoxDecoration(
              color: black,
              boxShadow: [
                BoxShadow(
                  color: shadowColorGlobal,
                  blurRadius: 10,
                  spreadRadius: 2,
                ),
              ],
            ),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                Flexible(
                  child: tabItem(0, 'assets/images/icons/home.png'),
                  flex: 1,
                ),
                Flexible(
                  child: tabItem(1, 'assets/images/icons/ballot-check.png'),
                  flex: 1,
                ),
                Flexible(
                  child: tabItem(2, 'assets/images/icons/plane-departure.png'),
                  flex: 1,
                ),
                Flexible(
                  child: tabItem(3, 'assets/images/icons/search-alt.png'),
                  flex: 1,
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

我已经尝试过:

  • 确保PageController在dispose方法中被释放。
  • 检查控制器处置后是否有可能尝试使用该控制器的任何异步操作。
  • 在我的代码库或第三方包中搜索 PagingController 的任何间接使用。
  • 任何关于可能导致此异常的原因以及如何解决该异常的见解或建议将不胜感激。
flutter dart infinite-scroll
1个回答
0
投票

您可以使用 TabController 移动其他选项卡此链接来查看它 https://api.flutter.dev/flutter/material/TabController-class.html

© www.soinside.com 2019 - 2024. All rights reserved.