Flutter 在initState時自動彈出提示框
需求:
剛一進入頁面,檢測用戶是否認證了,如果沒有認證則彈出提示框
問題原因:
由於Flutter的Alert提示框是需要頁面內容Build完畢後,並且有了父級頁面內容的時候,纔可以進行正常的彈出,所以在一開始 initState的時候,就調用彈出方法,便會報錯出現問題
。
解決辦法一:
此辦法是在有了上下文的context的情況下,也就是說在調用的時候context是存在的情況下可以使用
使用一個定時器去解決,在頁面加載後延時調用,這個辦法就解決了,我使用的是秒,延遲了1秒,用戶體驗上感覺不到什麼,完美解決這個問題。附代碼↓
注
:AlertMsg.alerDialog是我封裝的方法,所以請替換爲自己的。封裝的方法也給附代碼了
var _isAuthentication = false;
@override
void initState() {
super.initState();
// 避免調用Alert時沒有加載完父級頁面,延遲1秒調用
Timer(Duration(seconds: 1), () => _getUserIsAuthentication());
}
_getUserIsAuthentication(){
if(!_isAuthentication){
AlertMsg.alertDialog(context, '你還沒有實名認證呦,趕快認證成爲主播或專家吧', '立即認證', '先不認證', (){
Navigator.pop(context);
Navigator.pushNamed(context, '/myAuthentication');
});
}
}
AlertMsg
注
:ScreenAdapter爲封裝的自適應大小,具體可參考我另外一篇Flutter 裝修計劃
import 'package:firetiger/utils/ScreenAdapter.dart';
import 'package:flutter/material.dart';
class AlertMsg {
static alertDialog(context, text, confirmText, cancelText, confirmFn){
showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context){
return AlertDialog(
content: Text('$text', style: TextStyle(fontWeight: FontWeight.bold, fontSize: ScreenAdapter.size(30))),
backgroundColor: Colors.white,
elevation: 24,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
actions: <Widget>[
Container(
width: ScreenAdapter.setWidth(200),
child:OutlineButton(
borderSide: BorderSide(color: Theme.of(context).primaryColor),
highlightedBorderColor: Theme.of(context).primaryColor,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
child: Text('$cancelText', style: TextStyle(color: Theme.of(context).primaryColor),),
onPressed: (){
Navigator.pop(context);
},
),
),
SizedBox(
width:ScreenAdapter.setWidth(10)
),
Container(
width: ScreenAdapter.setWidth(200),
child: RaisedButton(
color: Theme.of(context).primaryColor,
highlightColor:Theme.of(context).primaryColor,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
child: Text('$confirmText', style: TextStyle(color: Colors.white),),
onPressed:confirmFn
),
)
],
);
}
);
}
}
解決辦法二:
當然還有一種原因就是在initState調用時候沒有context
上下文,那麼我們可以使用Future.delayed
去調用,這樣也算解決了此問題
void initState() {
// TODO: implement initState
super.initState();
Future.delayed(
Duration.zero,
AlertMsg.alertDialog(context, '你還沒有實名認證呦,趕快認證成爲主播或專家吧', '立即認證', '先不認證', (){
Navigator.pop(context);
Navigator.pushNamed(context, '/myAuthentication');
});
);
}`