Reputation: 325
I'm having a problem with my app.
The situation is: i have a very simple login system on the app and i save the logged user using SharedPreferences. But if the user leaves the app and then return it will open the login screen again, so i want to skip the login screen if the user is logged.
So in my main i put a function to check if there is login information, if yes it would redirect right to the app page or to the login page if not. But when i try to call the app page it always calls the page setted on the Home part.
How can i solve this? Is there any way to make it ignore the Home? Is there a way to make the "if" part on the home? Would be the better solution but its not possible.
Also i know i'm not using the best way to make this control, but it works (despite of this problem i have now, sure) and if you have any tips on making it better i would appreciate.
Heres my code:
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
void main() => runApp(new MyApp());
class _MyAppState extends State<MyApp> {
Future<void> verificaLogin() async {
print("running ok"); //just to test if the function runs
final prefs = await SharedPreferences.getInstance();
final key = 'usuario';
final value = prefs.getString(key);
print('saved tester $value');
String usu = value; /
if (usu.isEmpty) {
BuildContext context;
Navigator.push(
context,
MaterialPageRoute(builder: (context) => LoginScreen()), //sends to loginscreen if not logged
);
}
if (usu.isNotEmpty) {
BuildContext context;
Navigator.of(context)
.pushReplacement(MaterialPageRoute(builder: (context) => Pedidos())); //sends to main (not main.dart) app page
}
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => verificaLogin());
}
Widget build(BuildContext context) {
return BotToastInit(
child: MaterialApp(
navigatorObservers: [BotToastNavigatorObserver()],
title: "Test App",
theme: ThemeData(
primarySwatch: Colors.green,
),
debugShowCheckedModeBanner: false,
home: LoginScreen(), //i'm calling the loginscreen, it ignores the function on the top
),
);
}
}
Upvotes: 0
Views: 92
Reputation: 66
Hi you can use a FutureBuilder at vefiricaLoigin, and then Material App at home use verificaLogin, https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
verificaLogin() {
return FutureBuilder<Widget>(
future: SharedPreferences.getInstance(),
builder: (BuildContext context, prefs) {
final key = 'usuario';
final value = prefs.getString(key);
String usu = value;
if (usu.isEmpty) {
return LoginScreen()l
} else {
return Pedidos();
}
);
}
Widget build(BuildContext context) {
return MaterialApp(
title: "Test App",
theme: ThemeData(
primarySwatch: Colors.green,
),
debugShowCheckedModeBanner: false,
home: verificaLogin()
);
}
Upvotes: 0
Reputation: 1347
Please make one SplashScreen like below it resolves your issue..
and call this as home: SplashScreen(),
class SplashScreen extends StatefulWidget {
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
String loginData = "";
SharedPreferences sharedPreferences;
void initState() {
super.initState();
readFromStorage();
}
void readFromStorage() async {
sharedPreferences = await SharedPreferences.getInstance();
final key = 'usuario';
loginData = sharedPreferences.getString(key);
if (loginData.isNotEmpty) {
Future.delayed(const Duration(milliseconds: 3000), () {
setState(() {
Navigator.of(context)
.pushReplacement(MaterialPageRoute(builder: (context) => Pedidos()));
});
});
} else {
Future.delayed(const Duration(milliseconds: 3000), () {
setState(() {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => LoginScreen()),);
});
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlutterLogo(
size: 100.0,
),
],
)),
);
}
}
Upvotes: 1