首页 > 解决方案 > Flutter Provider:未处理的异常:查找已停用小部件的祖先是不安全的

问题描述

我是扑扑和飞镖的菜鸟。在尝试颤振提供者状态管理包时,我收到以下错误:

[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe.
    At this point the state of the widget's element tree is no longer stable.
    To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.
E/flutter (23887): #11     _rootRun (dart:async/zone.dart:1184:13)
E/flutter (23887): #12     _CustomZone.run (dart:async/zone.dart:1077:19)
E/flutter (23887): #13     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:1003:23)
E/flutter (23887): #14     Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:23:15)
E/flutter (23887): #15     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:398:19)
E/flutter (23887): #16     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:429:5)
E/flutter (23887): #17     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)

我想做什么?

我想创建一个标签栏。选项卡项将从服务器动态获取。然后我将单击选项卡,它们将按类别 id 加载用户提要帖子。如果我在选项卡之间滑动,它不会引发任何错误。如果我一个一个地点击选项卡项目,它不会引发任何错误。但是如果我点击第二个下一个项目,它会抛出上面指定的错误。这是我的代码

FeedListScreen.dart:

    import 'package:flutter/material.dart';
    import 'package:flutter_x/Providers/FeedProvider.dart';
    import 'package:flutter_x/Widgets/FeedList.dart';
    import 'package:provider/provider.dart';
    
    class FeedListScreen extends StatefulWidget {
    
      @override
      _FeedListScreenState createState() => _FeedListScreenState();
    }
    
    class _FeedListScreenState extends State<FeedListScreen> {
    
      bool _canLoadTabs = false;
      List<Tab> _tabs = [];
      List<Widget> _tabContainers = [];
    
      @override
      void initState() {

        Future.delayed(Duration(seconds: 0), () {
          var fp = Provider.of<FeedProvider>(context, listen: false);
          fp.fetchFeedTypes().then((value) {
            for (int i = 0; i < fp.feedTypeList.length; i++) {
              _tabs.add(Tab(text: fp.feedTypeList[i].name,));
              _tabContainers.add(FeedList(fp.feedTypeList[i].id));
            }
    
            setState(() {
              _canLoadTabs = true;
            });
          }
          );
        });
        super.initState();
      }
   
    
      @override
      Widget build(BuildContext context) {
    
        return Consumer<FeedProvider>(
          builder: (ctx, feedProvider, _) {
            if (!_canLoadTabs) {
              return Center(child: CircularProgressIndicator());
            }
    
            return DefaultTabController(
                length: _tabs.length,
                child: Scaffold(
                  appBar: AppBar(
                            bottom: TabBar(
                            tabs: _tabs,
                            isScrollable: true,
                          ),
                       ),
                  body: TabBarView(
                    children: _tabContainers,
                  ),
                )
            );
          },
        );
      }
    }

FeedList.dart

import 'package:flutter/material.dart';
import 'package:flutter_x/Providers/FeedProvider.dart';
import 'package:provider/provider.dart';

class FeedList extends StatelessWidget {
  String _id;

  FeedList([String id]) {
    _id = id;
  }

  @override
  Widget build(BuildContext context) {
    
Future.delayed(Duration(seconds: 0), () {
      if (_id == null) {
        print('_id is null.. not fetching');
      } else {
        Provider.of<FeedProvider>(context, listen: false).fetchFeedList(page: 1, feedId: _id); //<= This line causing the error
      }
    });

    return ListView.builder(
      shrinkWrap: true,
      itemCount: 20, //dummy
      itemBuilder: (ctx, index) => ListTile(
        leading: CircleAvatar(
          child: Text('$index'),
        ),
      ),
    );
  }
}

FeedProvider.dart

    import 'package:flutter/material.dart';
    
class FeedProvider with ChangeNotifier {
    
      List<FeedType> _feedTypes = [];
      List<FeedItem> _feedItemList = [];
    
    ///getters
      List<FeedType> get feedTypeList => _feedTypes;
      List<FeedItem> get feedList => _feedItemList;
      .... other getters...
    ///setters
      ... other setters...
    
    set feedTypeList(List<FeedType> ft) {
        if (_feedTypes != ft) {
          _feedTypes = ft;
          notifyListeners();
        }
      }
    
      set feedList(List<FeedItem> fl) {
        if(fl.length == 0){
          _feedItemList = [];
        }else{
          _feedItemList.addAll(fl);
        }
          notifyListeners();
      }
    
    ///methods
      Future<void> fetchFeedTypes() async {
    
        feedTypeLoaderStatus = true;
        error = '';
        try {
          var data = await _feedService.fetchFeedTypes(); //...http call
    
          List<FeedType> rawFeedTypes = [];
          for (int i = 0; i < data.length; i++) {
            rawFeedTypes.add(FeedType.fromJson(data[i]));
          }
    
          feedTypeList = rawFeedTypes;
    
        } catch (err) {
          //...error handling codes
        } finally {
          feedTypeLoaderStatus = false;
        }
      }
    
      Future<void> fetchFeedList({@required int page, String feedId}) async {
       
   if(page == 1){
          feedList = [];
        }
    
    try {
          Map<String, dynamic> queryParams = {"page": page.toString()};
    
          if(feedId != null){
            queryParams["feed_type_id"] = feedId;
          }
    
          var data = await _feedService.fetchFeedList(queryParams); //...http calls 
    
          List<FeedItem> rawFeedList = [];
          for (int i = 0; i < data.length; i++) {
            rawFeedList.add(FeedItem.fromJson(data[i]));
          }
    
          feedList = rawFeedList;
        } catch (err) {
          feedList = [];
          //.... error handling codes
        } finally {
          feedLoaderStatus = false;
        }
      }
    }

截屏 在此处输入图像描述

无法弄清楚这里的错误。欢迎任何建议/代码改进

标签: flutterdartflutter-provider

解决方案


推荐阅读