flutter - 来自 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
);
});
}
}
解决方案
当应用程序首次运行时显示您的徽标或加载程序时,创建启动画面。
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 或您想要重定向的任何内容,但如果不是,则重定向到商店
推荐阅读
- express - 我可以使用 Express res.sendFile() 发送 XLS/XLSX 文件吗?
- javascript - 如何将我的 expo 应用程序发布到 Apple 应用商店?
- json - 将 pandas 数据帧转换为具有特定格式的 json
- javascript - 如何在产品列表中添加切换“全部显示”、“全部隐藏”
- python - 为什么这没有返回预期的升序?
- spring-boot - Springboot + Elastic Search:如何构建模糊的 LIKE 查询?
- javascript - 来自数组的动态 HTML 行
- amazon-s3 - AWS 胶水将动态帧写入内存不足 (OOM)
- haskell - 是否有一个 Monad 收集结果并将其映射到它们?
- delphi - 未声明的标识符 soAllDirectories