首页 > 解决方案 > 来自 initState Flutter 中调用的异步函数的 ShowDialog

问题描述

我正在编写代码来检查用户是否安装了我的应用程序的正确版本,否则将他重定向到 Playstore 以更新应用程序。

firebase_remote_config用来存储一个变量来保存我希望用户使用的最低版本。

Package_info获取有关用户应用程序的信息。

url_launcher从应用程序重定向到 Playstore

我的问题是我检查版本的方法是异步的,它需要在进入应用程序的第一个屏幕之前向用户显示对话框。

我在initState. 但是构建方法在我的异步函数结束之前构建了第一个屏幕并且我ShowDialog没有渲染。

如何在第一次构建之前首先显示我的异步函数的结果?

这是我在一些更新后的代码,但在导航到另一个屏幕之前没有显示对话框

class Splashscreen extends StatefulWidget {


  @override
  _SplashscreenState createState() => _SplashscreenState();
  }

  class _SplashscreenState extends State<Splashscreen> {

  @override
  void initState() {

  super.initState();

  SchedulerBinding.instance.addPostFrameCallback((_) {
  versionCheck(context);
  });

  }

 

 Future versionCheck(context) async {
  //Get Current installed version of app

  final PackageInfo info = await PackageInfo.fromPlatform();
  double currentVersion =
  double.parse(info.version.trim().replaceAll(".", ""));

  //Get Latest version info from firebase config
  final RemoteConfig remoteConfig = await RemoteConfig.instance;

  try {
  // Using default duration to force fetching from remote server.
  await remoteConfig.fetch(expiration: const Duration(seconds: 10));
  await remoteConfig.activateFetched();
  remoteConfig.getString('force_update_current_version');
  double nVersion = double.parse(remoteConfig
      .getString('force_update_current_version')
      .trim()
      .replaceAll(".", ""));

  if(nVersion > currentVersion){

  showDialog(
  context: context,
  builder: (_) => new AlertDialog(
  title: new Text("You are not up to date"),
  content: new Text("To use the application, you must update it"),
  actions: <Widget>[
  FlatButton(
  child: Text('Go To Store'),
  onPressed: () {
  _launchURL(PLAY_STORE_URL);
  },
  )
  ],
  )
  );

  }

  } on FetchThrottledException catch (exception) {

  print(exception);
  } catch (exception) {
  print(
  'Unable to fetch remote config. Cached or default values will be used');
  }
  }



  _launchURL(String url) async {
  if (await canLaunch(url)) {
  await launch(url);
  } else {
  throw 'Could not launch $url';
  }
  }


  

@override
  Widget build(BuildContext context) {
  return ScopedModelDescendant<UserModel>(builder: (context, child, model) {
  return new SplashScreen(

  seconds: 4,
  navigateAfterSeconds:
  model.isSignedIn ? HomePage() : SuggestLoginPage(),

  image: new  Image.asset('assets/images/logo.png', fit: BoxFit.cover,),
  backgroundColor: Color(0xff131921),
  styleTextUnderTheLoader: new TextStyle( ),
  photoSize: 100.0,
  
                  loaderColor: Colors.white
              );
          });
      }
  }

标签: flutterdartasynchronousbuild

解决方案


当应用程序首次运行时显示您的徽标或加载程序时,创建启动画面。

    class SplashScreen extends StatefulWidget {
      @override
      _SplashScreenState createState() => _SplashScreenState();
    }
    
    cclass _SplashScreenState extends State<SplashScreen> {
  @override
  void initState() {
    super.initState();
    SchedulerBinding.instance.addPostFrameCallback((_) {
      checkVersion();
    });
  }

  Future checkVersion({String payload}) async {
    var upToDate = false;
    if (upToDate)
     print('Navigate to Home');
    else
      return showDialog(
        context: context,
        builder: (_) => new AlertDialog(
          title: new Text("You are not up to date"),
          content: new Text("To use the application, you must update it"),
          actions: <Widget>[
            FlatButton(
              child: Text('Go To Store'),
              onPressed: () {
                //navigate to store
              },
            )
          ],
        )
      );
  }
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Colors.white,
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  "Stackowerflow",
                  style: TextStyle(
                    fontFamily: "Josefin",
                    fontSize: 55,
                    fontWeight: FontWeight.bold,
                    color: Colors.grey,
                  ),
                ),
                Image.asset('assets/images/splash.gif',width: 500,
                  height: 500,),
              ],
            ),
          ),
        );
      }

不要忘记在 main.dart 中运行这个启动画面

现在您可以将您的函数添加到 checkVersion 中,如果是最新的,则返回 home 或您想要重定向的任何内容,但如果不是,则重定向到商店


推荐阅读