【问题标题】:ShowDialog from an asynchronus function called in initState Flutter来自 initState Flutter 中调用的异步函数的 ShowDialog
【发布时间】:2021-02-26 16:55:08
【问题描述】:

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

我正在使用firebase_remote_config 来存储一个变量,以记录我希望用户使用的最低版本。

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

url_launcher 从应用重定向到 Playstore

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

我在initState 中执行它。但是 build 方法在我的异步函数结束之前构建了第一个屏幕,并且我的 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
              );
          });
      }
  }

【问题讨论】:

    标签: flutter dart asynchronous build


    【解决方案1】:

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

        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 或您想要重定向的任何内容,但如果不是,则重定向到商店

    【讨论】:

    • 感谢您的回答,但还没有工作...我想显示的对话框没有显示,因为我们已经在启动屏幕之后导航到另一个屏幕...有什么建议吗?
    • 不工作...请我添加我不知道的代码也许我做错了什么
    • 我回答了您的问题,请关闭此问题,将该答案标记为有效,然后搜索如何检查版本控制或提出问题。
    • 感谢您的回答......对我帮助很大......即使显示 AlertDialog,它也会在不点击任何按钮的情况下随着导航消失......这是我现在的最后一个问题...... .
    猜你喜欢
    • 2021-07-07
    • 2020-07-28
    • 2020-07-15
    • 2021-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-29
    • 2023-03-06
    相关资源
    最近更新 更多