首页 > 解决方案 > Navigator.push 不适用于颤振中的 setState

问题描述

Navigator.push 不适用于setState.

一旦我删除了retry()函数中的 setState ,它就可以工作了,但我想在retry函数中使用 setState 。

import 'package:covid_19/screens/home.dart';
import 'package:covid_19/viewmodel/home_view_model.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyAppError());

class MyAppError extends StatefulWidget {
  @override
  _MyAppErrorState createState() => _MyAppErrorState();
}

class _MyAppErrorState extends State<MyAppError> {
  bool _loading = false;
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return _loading ? CircularProgressIndicator() : MaterialApp(
      home: Scaffold(
          key: _scaffoldKey,
          body: Builder(
                builder:(context)=> 
              SafeArea(
                child: Container(
                  margin: EdgeInsets.all(10),
                  child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Text(
                      "No internet found. Check your connection",
                      textAlign: TextAlign.center,
                    ),  
                    FlatButton(
                      child: Text('Retry'),
                      onPressed: retry,
                    )
                  ],
                ),
              ),
            ),
          ),
      )
    );
  }

  Future<void> retry() async{
    setState(() {
      _loading = true;
    });
    print('retrying...');
    HomeViewModel homeViewModel = HomeViewModel();
    homeViewModel.onAppStart().then((_){
      print('pushing');
      Navigator.pushReplacement(_scaffoldKey.currentContext, MaterialPageRoute(builder: (context)=> Home(data : homeViewModel.data)));
    }).catchError((e){
      setState(() {
        _loading = false;
      });
    });
    
  }
}

没有点击重试按钮时的日志setState

retrying...
pushing... 
and navigate to Home()

单击重试按钮时记录setState

retrying...
pushing... 
and nothing happens

标签: flutterdart

解决方案


它有一个逻辑错误。当 _loading 为 true 时,没有脚手架,您正在使用 Scaffold 键进行导航。

尝试这个。

    import 'package:covid_19/screens/home.dart';
import 'package:covid_19/viewmodel/home_view_model.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyAppError());

class MyAppError extends StatefulWidget {
  @override
  _MyAppErrorState createState() => _MyAppErrorState();
}

class _MyAppErrorState extends State<MyAppError> {
  bool _loading = false;
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          key: _scaffoldKey,
          body:_loading ? CircularProgressIndicator() : Builder(
              builder:(context)=> 
              SafeArea(
                child: Container(
                  margin: EdgeInsets.all(10),
                  child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Text(
                      "No internet found. Check your connection",
                      textAlign: TextAlign.center,
                    ),  
                    FlatButton(
                      child: Text('Retry'),
                      onPressed: retry,
                    )
                  ],
                ),
              ),
            ),
          ),
      )
    );
  }

  Future<void> retry() async{
    setState(() {
      _loading = true;
    });
    print('retrying...');
    HomeViewModel homeViewModel = HomeViewModel();
    homeViewModel.onAppStart().then((_){
      print('pushing');
      Navigator.pushReplacement(_scaffoldKey.currentContext, MaterialPageRoute(builder: (context)=> Home(data : homeViewModel.data)));
    }).catchError((e){
      setState(() {
        _loading = false;
      });
    });
    
  }
}

推荐阅读