如何让启动画面在导航到下一个屏幕之前等待计算?
How can I make splash screen wait for computations before navigating to next screen?
我正在 flutter 上制作启动画面,我想 运行 在显示启动画面时进行一些计算(带有圆形进度指示器 运行ning),在完成所有计算之后我想要 运行 a Navigator.push() 导航到主屏幕。问题是 flutter 从不等待计算,我所做的解决方法是在我的导航器中添加一个 future.delayed() 并等待任意时间直到所有计算完成。
代码是这样的:(计算是加载的模型)
class SplashScreen extends StatefulWidget {
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
@override
void initState() {
super.initState();
SchedulerBinding.instance.addPostFrameCallback((_) {
// Do all of this
final bestModel = Provider.of<BestSellingModel>(context, listen: false);
final salesModel = Provider.of<SalesModel>(context, listen: false);
final categoryModel = Provider.of<CategoryModel>(context, listen: false);
if (bestModel.isLoading) bestModel.getBestSelling();
if (salesModel.isLoading) salesModel.getSales();
if (categoryModel.isLoading) categoryModel.getCategories();
DatabaseHelper.instance.database;
// And only then navigate to next screen without a pre-established time
Future.delayed(Duration(seconds: 12), () {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (BuildContext context) => MainTabs()));
});
});
}
@override
Widget build(BuildContext context) {
Size screenSize = MediaQuery.of(context).size;
return Scaffold(
body: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [Color(0xffFBC707), Color(0xffF25D19)],
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 2,
child: Container(
width: screenSize.width / 1.8,
child: Image.asset('assets/images/splash_logo.png'),
),
),
Expanded(
flex: 1,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// This needs to keep running while the models are being loaded
SizedBox(
child: CircularProgressIndicator(),
height: 64.0,
width: 64.0,
),
],
),
)
],
)
],
),
);
}
}
这是我使用的模型示例:
class SalesModel with ChangeNotifier{
List<Product> products = [];
bool isLoading = true;
Future getSales() async {
products = await WooCommerce().getProductsByCategory(categoryId: 58);
isLoading = false;
notifyListeners();
}
}
那么,有没有办法在加载模型的同时让启动画面的循环进度指示器运行并在加载所有模型后导航到主屏幕?
我对登录状态做了类似的事情。
我的 splash 监听登录状态流。
void setInProgress(bool value) {
setState(() {
_inProgress = value;
});
} // of setInProgress
在你的构建方法中,你可以添加条件
if (_inProgress)
Center(
child: CircularProgressIndicator(),
)
if (!_inProgress)
Center(
child: HomeScreenWidget(),
)
每次我这样做的时候,我都觉得我真的应该把它封装在一个小部件中。
此外,如果计算状态不仅仅是一个布尔值,您可以使用 StreamBuilder 来侦听计算状态流。
我正在 flutter 上制作启动画面,我想 运行 在显示启动画面时进行一些计算(带有圆形进度指示器 运行ning),在完成所有计算之后我想要 运行 a Navigator.push() 导航到主屏幕。问题是 flutter 从不等待计算,我所做的解决方法是在我的导航器中添加一个 future.delayed() 并等待任意时间直到所有计算完成。
代码是这样的:(计算是加载的模型)
class SplashScreen extends StatefulWidget {
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
@override
void initState() {
super.initState();
SchedulerBinding.instance.addPostFrameCallback((_) {
// Do all of this
final bestModel = Provider.of<BestSellingModel>(context, listen: false);
final salesModel = Provider.of<SalesModel>(context, listen: false);
final categoryModel = Provider.of<CategoryModel>(context, listen: false);
if (bestModel.isLoading) bestModel.getBestSelling();
if (salesModel.isLoading) salesModel.getSales();
if (categoryModel.isLoading) categoryModel.getCategories();
DatabaseHelper.instance.database;
// And only then navigate to next screen without a pre-established time
Future.delayed(Duration(seconds: 12), () {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (BuildContext context) => MainTabs()));
});
});
}
@override
Widget build(BuildContext context) {
Size screenSize = MediaQuery.of(context).size;
return Scaffold(
body: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [Color(0xffFBC707), Color(0xffF25D19)],
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 2,
child: Container(
width: screenSize.width / 1.8,
child: Image.asset('assets/images/splash_logo.png'),
),
),
Expanded(
flex: 1,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// This needs to keep running while the models are being loaded
SizedBox(
child: CircularProgressIndicator(),
height: 64.0,
width: 64.0,
),
],
),
)
],
)
],
),
);
}
}
这是我使用的模型示例:
class SalesModel with ChangeNotifier{
List<Product> products = [];
bool isLoading = true;
Future getSales() async {
products = await WooCommerce().getProductsByCategory(categoryId: 58);
isLoading = false;
notifyListeners();
}
}
那么,有没有办法在加载模型的同时让启动画面的循环进度指示器运行并在加载所有模型后导航到主屏幕?
我对登录状态做了类似的事情。 我的 splash 监听登录状态流。
void setInProgress(bool value) {
setState(() {
_inProgress = value;
});
} // of setInProgress
在你的构建方法中,你可以添加条件
if (_inProgress)
Center(
child: CircularProgressIndicator(),
)
if (!_inProgress)
Center(
child: HomeScreenWidget(),
)
每次我这样做的时候,我都觉得我真的应该把它封装在一个小部件中。 此外,如果计算状态不仅仅是一个布尔值,您可以使用 StreamBuilder 来侦听计算状态流。