I would like to check the authentication login state as below
- authentication loading => show splash screen
- authenticated=> home screen
- unauthenticated=>sign in screen
Currently, I am using GetX state management I wish, on authentication loading state then show flutter_native_splash_screen rather than my customize splash screen due to rendering, it shows a black screen before my customized splash finished render.
Here is my code
void main() async {
var widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
internalInitialized();
runApp(const MyApp());
FlutterNativeSplash.remove();
}
void internalInitialized() {
Get.lazyPut(() => AuthController(Get.put(AuthService())));
}
class MyApp extends GetWidget<AuthController> {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return GetMaterialApp(
debugShowCheckedModeBanner: false,
home: Obx(() {
if (controller.state is Authenticated) {
return HomeScreen((controller.state as Authenticated).user!);
} else if (controller.state is UnAuthenticated) {
return SignInScreen();
} else {
return const SplashScreen();
}
}),
theme: lightTheme(),
darkTheme: darkTheme(),
getPages: AppPages.list,
);
}
}
Splash Screen
class SplashScreen extends StatelessWidget {
const SplashScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
SizeConfig.init(context);
return Container(
color: AppTheme.primaryColor,
width: SizeConfig.screenWidth,
height: SizeConfig.screenHeight,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: getHeight(150),
height: getHeight(150),
child: Image.asset("assets/images/logo.png"),
),
const CircularProgressIndicator(color: Colors.white)
],
));
}
}
The customize splash screen just show Logo and processing bar. Auth Controller
class AuthController extends ConnectivityController {
final AuthService authService;
final authStateStream = const AuthenticationState().obs;
AuthController(this.authService);
AuthenticationState get state => authStateStream.value;
@override
void onInit() {
getAuthenticatedUser();
super.onInit();
}
Future<void> signIn(String username, String password) async {
authStateStream.value = AuthenticationLoading();
final customer = await authService.sign(username, password);
if (customer == null) {
authStateStream.value = UnAuthenticated();
} else {
authStateStream.value = Authenticated(customer: customer);
}
}
void signOut() async {
await authService.signOut("");
authStateStream.value = UnAuthenticated();
}
void getAuthenticatedUser() async {
authStateStream.value = AuthenticationLoading();
Future.delayed(const Duration(seconds: 10));
final customer = await authService.reSignIn();
if (customer == null) {
authStateStream.value = UnAuthenticated();
} else {
authStateStream.value = Authenticated(customer: customer);
}
}
}
Please guide me, on how can I solve this issue. Thank you!
CodePudding user response:
The splash screen is meant to be displayed whilst the bundled Flutter engine initialises. Once that is done and your app is in control, you can manually create a page that looks like the splash screen. So the child of the material app can be a splash screen look alike. Maybe you could even make it identical to your splash screen asset.
CodePudding user response:
Try this,
first initialize
your state and use conditional
operator if it is authenticated than go to splashScreen
else authenticate
.
void initState() {
super.initState();
var _isAuth = user != null && user.isVerified;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => _isAuth ? SplashScreen() : Authenticate()),
);
}