【问题标题】:Flutter: My notifyListeners() doesn't work, but only in the release apkFlutter:我的 notifyListeners() 不起作用,但仅在发布 apk 中起作用
【发布时间】:2023-02-03 20:42:06
【问题描述】:

我有一个页面在进行 API 调用时显示加载,调用完成后它会显示接收到的数据。

在调试器上一切正常,但是当我使用“flutter build apk”创建 apk 并下载它时,加载会无限期地保持下去。

我还在进行 API 调用的 Provider 函数的末尾放置了一个 showDialog(我将此 showDialog 放置在 notifyListeners() 下方。

我不明白为什么在调试中它可以工作而在发布时却不能。

(这个 notifyListeners 不起作用只是对我进行的每个 API 调用都起作用)

这是进行 api 调用的提供程序函数的代码:

Future<void> getUserSites(context) async {
     _userSites.clear();
     isLoading = true;
     notifyListeners(); 
     try { 
       final response = await NetworkService.call( 
           url: '/api/structure/Sites', 
           method: Method.Get, 
           context: context) as List<dynamic>;      
     for (var i = 0; i < response.length; i++) {
        _userSites.add(Sites.fromJson(response.elementAt(i)));
      }

      if (defaultSite == null) {
        if (SimplePreferences.getDefaultSite() == null) {
          defaultSite = _userSites.isNotEmpty ? _userSites.first : null;
          if (defaultSite != null) {
            SimplePreferences.setDefaultSite(defaultSite!.id);
          }
        } else {
          defaultSite = _userSites.firstWhere(
              (element) => element.id == SimplePreferences.getDefaultSite()!);
        }
      }

  
    } catch (e) {
      inspect(e);
      if (SimplePreferences.getToken() != null) {
        showDialog(
          context: context,
          builder: (ctx) => AlertDialog(
            title: const Text('General Error'),
            content: Text(e.toString()),
            actions: [
              TextButton(
                onPressed: () {
                  Navigator.of(context).pop();
                },
                child: const Text(
                  'Ok',
                ),
              )
            ],
          ),
        );
      }
      // throw e;
    }
    isLoading = false;
    notifyListeners();
    showDialog(
          context: context,
          builder: (ctx) => AlertDialog(
            title: const Text('getUserSites done!'),
            content: Text(_userSites.toString()),
            actions: [
              TextButton(
                onPressed: () {
                  Navigator.of(context).pop();
                },
                child: const Text(
                  'Ok',
                ),
              )
            ],
          ),
        );
  }

这是主页代码:

class HomePageScreen extends StatelessWidget { const HomePageScreen({super.key}); static const String routeName = '/';

@override Widget build(BuildContext context) { log('New Page: Home Page'); final provider = Provider.of<MyManager>(context);
return provider.isLoading ? const Center(
        child: CircularProgressIndicator(),
      )
    : SingleChildScrollView(
        physics: const BouncingScrollPhysics(),
        child: Container(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              MainButton(
                onTap: () async {
                    Navigator.of(context)
                      .pushNamed(ShowPatrolScreen.routeName);
                      await provider.getPatrol(context);
                },
                icon: Icons.home,
                title: 'ShowPatrol',
              ),
              printSito(provider.defaultSite?.description ?? 'Nessun Sito', context),
              PrintRequestZ(
                showCompleted: false,
              ),
            ],
          ),
        ),
      );
}

Widget printSito(String name, context) { .... //pass context for Navigator and Theme } } `

这是主页:

...
final myScreens = [
     const HomePageScreen(),
     ...
];

@override
void initState() {
    // TODO: implement initState
    super.initState();
    print('token: ${SimplePreferences.getToken()}');
    if (SimplePreferences.getToken() == null){
       Navigator.of(context).pushReplacementNamed('/Auth');
    }
    var provider = Provider.of<MyManager>(context, listen: false);
    provider.setAll(context); //this function calls all my API calls, but for testing, I commented out all other functions and kept only the one written above
}

@override
Widget build(BuildContext context) {
    var provider = Provider.of<MyManager>(context);
    return Scaffold(
      appBar: const MyAppBar(title: 'Ronda',canGoBack: false,),
      body: myScreens[currentPage],
      bottomNavigationBar: ...
    ),
}

提前致谢!

【问题讨论】:

  • 您使用的是哪种提供商?

标签: flutter flutter-provider renderui


【解决方案1】:

使用 Consumer 访问 Provider 的变量

return Consumer<YourProviderName>(builder : (context, value, child){
return value.isLoading? const Center(
    child: CircularProgressIndicator(),
  ):YourWidget(),
});

【讨论】:

  • 你可能应该解释你的答案。纯代码答案很少有帮助。
猜你喜欢
  • 2020-07-11
  • 1970-01-01
  • 1970-01-01
  • 2020-09-16
  • 1970-01-01
  • 2020-12-10
  • 1970-01-01
  • 2016-09-07
  • 2019-07-30
相关资源
最近更新 更多