Flutter BlocBuilder颤振中如何延迟返回屏幕
在我的应用程序中,我使用Flutter BlocBuilder颤振中如何延迟返回屏幕,flutter,bloc,Flutter,Bloc,在我的应用程序中,我使用flatter\u bloc进行状态管理,在main()中,我使用BlocBuilder进行身份验证,如果它收到一个Authenticated状态返回MapScreen,如果状态是Unauthenticated则返回LoginScreen,否则返回飞溅屏幕。我想控制Splashscreen的显示时间,所以我尝试在BlocBuilder的内部状态检查中添加一个计时器,但它从未返回屏幕。如何设置Splashscreen在一定时间内保持可见? 一如既往,非常感谢您的时间和帮助。
flatter\u bloc
进行状态管理,在main()中,我使用BlocBuilder
进行身份验证,如果它收到一个Authenticated
状态返回MapScreen
,如果状态是Unauthenticated
则返回LoginScreen
,否则返回飞溅屏幕
。我想控制Splashscreen的显示时间,所以我尝试在BlocBuilder的内部状态检查中添加一个计时器,但它从未返回屏幕。如何设置Splashscreen
在一定时间内保持可见?
一如既往,非常感谢您的时间和帮助。
这是BlocBuilder的
home: BlocBuilder<AuthenticationBloc, AuthenticationState>(
builder: (context, state) {
if (state is Unauthenticated) {
// Timer(Duration(seconds: 10), () {
return LoginScreen(userRepository: _userRepository);
// });
}
if (state is Authenticated) {
// Timer(Duration(seconds: 50), () {
return MultiBlocProvider(
providers: [
BlocProvider<DefaultsBloc>(
lazy: false,
create: (context) => DefaultsBloc()..add(InitializeRemote()),
),
BlocProvider<TrackingBloc>(
create: (context) => TrackingBloc(),
),
BlocProvider<DirectionsBloc>(
create: (context) => DirectionsBloc(),
),
BlocProvider<GeoBloc>(
create: (context) => GeoBloc(),
),
BlocProvider<RouteBloc>(
lazy: false,
create: (context) => RouteBloc(),
),
BlocProvider<SchedulerBloc>(
create: (context) => SchedulerBloc(),
),
BlocProvider<CheckerBloc>(
create: (context) => CheckerBloc(),
),
BlocProvider<LocationBloc>(
lazy: false,
create: (context) => LocationBloc(
mapRepository: _mapRepository,
)
..add(GetLocationStream())
..add(GetLocation())
..add(GetIsoLocationUser())),
BlocProvider<AlertBloc>(
create: (context) => AlertBloc(
alertRepository: _alertRepository, user: state.user),
),
BlocProvider<LocalNotificationBloc>(
lazy: false,
create: (context) => LocalNotificationBloc(),
)
],
child: MapScreen(
// mapRepository: _mapRepository,
user: state.user,
// alertRepository: FirebaseAlertRepository(),
),
);
// });
}
return SplashScreen();
},
),
home:BlocBuilder(
生成器:(上下文、状态){
如果(状态未经验证){
//计时器(持续时间(秒:10),(){
返回LoginScreen(userRepository:\u userRepository);
// });
}
如果(状态已验证){
//计时器(持续时间(秒数:50),(){
返回多BlocProvider(
供应商:[
BlocProvider(
懒惰:错,
create:(context)=>DefaultsBloc()…添加(InitializeRemote()),
),
BlocProvider(
create:(context)=>TrackingBloc(),
),
BlocProvider(
创建:(上下文)=>DirectionsBloc(),
),
BlocProvider(
create:(context)=>GeoBloc(),
),
BlocProvider(
懒惰:错,
create:(context)=>RouteBloc(),
),
BlocProvider(
create:(context)=>SchedulerBloc(),
),
BlocProvider(
create:(context)=>CheckerBloc(),
),
BlocProvider(
懒惰:错,
创建:(上下文)=>LocationBloc(
mapRepository:\u mapRepository,
)
…添加(GetLocationStream())
…添加(GetLocation())
…添加(GetIsLocationUser()),
BlocProvider(
创建:(上下文)=>AlertBloc(
alertRepository:_alertRepository,用户:state.user),
),
BlocProvider(
懒惰:错,
create:(context)=>LocalNotificationBloc(),
)
],
孩子:地图屏幕(
//mapRepository:\u mapRepository,
用户:state.user,
//alertRepository:FirebaseAlertRepository(),
),
);
// });
}
返回屏幕();
},
),
在生成方法中不能使用计时器。您可以创建一个新的StatefulWidget,然后在initState中添加一个计时器,该计时器将导航到下一个屏幕,这将是您当前用于home的小部件
import 'dart:async';
import 'package:flutter/material.dart';
class Splash extends StatefulWidget {
@override
_SplashState createState() => _SplashState();
}
class _SplashState extends State<Splash> {
@override
void initState() {
super.initState();
Timer(
const Duration(seconds: 1),
() => Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => OtherScreen()),
),
);
}
@override
Widget build(BuildContext context) {
return Material(
child: Center(
child: Text('Splash'),
),
);
}
}
导入'dart:async';
进口“包装:颤振/材料.省道”;
类Splash扩展StatefulWidget{
@凌驾
_SplashState createState()=>\u SplashState();
}
类的状态扩展了状态{
@凌驾
void initState(){
super.initState();
计时器(
常数持续时间(秒:1),
()=>Navigator.of(context.pushReplacement)(
MaterialPage路由(生成器:(上下文)=>OtherScreen()),
),
);
}
@凌驾
小部件构建(构建上下文){
退货(
儿童:中心(
子项:文本('Splash'),
),
);
}
}
我必须创建一个新事件StartApp
作为第一个发送到bloc的事件,然后在bloc中我设置了一个计时器来添加启动所有身份验证逻辑的AppStarted
事件
Stream<AuthenticationState> mapEventToState(
AuthenticationEvent event) async* {
if (event is StartApp) {
yield* _startAppToState();
}
if (event is AppStarted) {
yield* _mapAppStartedToState();
} else if (event is LoggedIn) {
yield* _mapLoggedInToState();
} else if (event is LoggedOut) {
yield* _mapLoggedOutToState();
}
}
Stream<AuthenticationState> _startAppToState() async* {
Timer(Duration(seconds: 5), () {
add(AppStarted());
});
}
Stream<AuthenticationState> _mapAppStartedToState() async* {
try {
final isSignedIn = await _userRepository.isSignedIn();
if (isSignedIn) {
final user = await _userRepository.getUser();
yield Authenticated(user);
} else {
yield Unauthenticated();
}
} catch (_) {
yield Unauthenticated();
}
}
流映射事件状态(
AuthenticationEvent(事件)异步*{
如果(事件为STARTAP){
产量*_startaptostate();
}
如果(事件已启动){
收益率*_mapAppStartedToState();
}else if(事件为LoggedIn){
收益率*_mapLoggedInToState();
}else if(事件为LoggedOut){
收益率*_maploggedoutstate();
}
}
流_startAppToState()异步*{
计时器(持续时间(秒数:5),(){
添加(AppStarted());
});
}
流\u mapAppStartedToState()异步*{
试一试{
final isSignedIn=await_userRepository.isSignedIn();
如果(伊西涅丁){
final user=wait_userRepository.getUser();
产量(用户);
}否则{
产生未经验证的();
}
}接住{
产生未经验证的();
}
}
我希望这能帮助其他人。
干杯。您好,谢谢您的回答,但这种方法只会延迟启动屏幕的加载,我想要的是延迟其他启动屏幕,以便使启动屏幕保持更长的可见时间。我在考虑用定时器来延迟各州的让步,而不是不用谢。我想这也是同样的道理。这将显示启动屏幕,然后在持续时间后,导航到另一个屏幕。生成带有计时器的状态不起作用。所以你答案中的代码应该是我的启动屏幕,对吗?是的,如果不是,你只需要将启动屏幕状态设为完整,然后将计时器(以你希望启动屏幕可见的持续时间)添加到initState
方法。好的,正如我所怀疑的那样,由于屏幕的显示取决于在BlocBuilder
中接收到的状态,所以这确实可以实现。一旦收到状态,它就会切换屏幕。因此,我认为推迟国家是唯一的选择。