颤振:如何显示用户特定的页面?
Posted
技术标签:
【中文标题】颤振:如何显示用户特定的页面?【英文标题】:FLUTTER : How to display user specific Page? 【发布时间】:2021-03-18 02:16:14 【问题描述】:尝试实现用户特定登录:登录后,如果用户是 A 类用户,则应显示不同的主页,如果用户是 B 类用户,则应显示单独的主页。 以下是登录小部件的代码:
class LogInWidget extends StatefulWidget
@override
_LogInWidgetState createState() => _LogInWidgetState();
class _LogInWidgetState extends State<LogInWidget>
var _formKey = GlobalKey<FormState>();
bool hide = true;
bool forgotPassword = false;
bool isLoginPressed = false;
final FirebaseAuth _auth = FirebaseAuth.instance;
final AuthMethods _authMethods = AuthMethods();
TextEditingController email = TextEditingController();
TextEditingController password = TextEditingController();
@override
Widget build(BuildContext context)
return isLoginPressed
? Center(
child: CircularProgressIndicator(),
)
: Scaffold(
backgroundColor: UniversalVariables.blackColor,
body: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.0),
child: ListView(
children: <Widget>[
SizedBox(
height: 80,
),
!forgotPassword
? Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(
'Sign In',
style: TextStyle(
color: Colors.white,
fontSize: 60,
fontWeight: FontWeight.w700),
textAlign: TextAlign.center,
),
SizedBox(
height: 48.0,
),
Material(
borderRadius: BorderRadius.circular(10.0),
elevation: 0.0,
color: Colors.white.withOpacity(0.2),
child: TextFormField(
cursorColor: Colors.white,
controller: email,
textAlign: TextAlign.center,
keyboardType: TextInputType.emailAddress,
// ignore: missing_return
validator: (String value)
if (value.isEmpty)
return "please enter a value";
,
style: TextStyle(
color: Colors.white,
),
decoration: kTextFieldDecoration.copyWith(
hintText: 'Enter your email',
prefixIcon: Icon(Icons.alternate_email,
color: Colors.white)),
),
),
SizedBox(
height: 8.0,
),
Material(
borderRadius: BorderRadius.circular(10.0),
elevation: 0.0,
color: Colors.white.withOpacity(0.2),
child: TextFormField(
cursorColor: Colors.white,
controller: password,
textAlign: TextAlign.center,
obscureText: hide,
// ignore: missing_return
validator: (String value)
if (value.isEmpty)
return "The password field cannot be empty";
,
style: TextStyle(
color: Colors.white,
),
decoration: kTextFieldDecoration.copyWith(
hintText: 'Enter your password',
prefixIcon: Icon(
Icons.lock_outline,
color: Colors.white,
),
suffixIcon: IconButton(
icon: Icon(
!hide
? Icons.remove_red_eye_outlined
: Icons.remove_red_eye,
color: Colors.white,
),
onPressed: ()
setState(()
hide = !hide;
);
,
),
),
),
),
Padding(
padding: const EdgeInsets.only(
top: 15, right: 8, bottom: 8),
child: InkWell(
onTap: ()
setState(()
forgotPassword = true;
);
,
child: Text(
'Forgot Password?',
textAlign: TextAlign.right,
style: TextStyle(
color: Colors.white,
),
),
),
),
SizedBox(
height: 18.0,
),
Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Material(
color: Colors.white,
borderRadius: BorderRadius.circular(30.0),
elevation: 2.0,
child: MaterialButton(
onPressed: () async
if (_formKey.currentState.validate())
performLogin();
,
minWidth: 200.0,
height: 42.0,
child: Text(
'Sign In',
style: TextStyle(color: Colors.black),
),
),
)),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'-OR-',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'sign in with',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 17),
),
),
googleSignInButton(),
],
))
: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Material(
borderRadius: BorderRadius.circular(10.0),
elevation: 0.0,
color: Colors.white.withOpacity(0.2),
child: Form(
key: _formKey,
child: TextFormField(
// ignore: missing_return
validator: (String value)
if (value.isEmpty)
return "please enter a value";
,
controller: email,
textAlign: TextAlign.center,
keyboardType: TextInputType.emailAddress,
style: TextStyle(
color: Colors.white,
),
decoration: kTextFieldDecoration.copyWith(
hintText: 'Enter your email',
prefixIcon: Icon(Icons.alternate_email,
color: Colors.white)),
),
),
),
SizedBox(
height: 18.0,
),
Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Material(
color: Colors.white,
borderRadius: BorderRadius.circular(30.0),
elevation: 2.0,
child: MaterialButton(
onPressed: () async
if (_formKey.currentState.validate())
ForgotPassword();
,
minWidth: 200.0,
height: 42.0,
child: Text(
'Continue',
style: TextStyle(color: Colors.black),
),
),
)),
Padding(
padding: const EdgeInsets.only(
top: 15, right: 8, bottom: 8),
child: Center(
child: InkWell(
onTap: ()
setState(()
forgotPassword = false;
);
,
child: Text(
'Sign In',
textAlign: TextAlign.right,
style: TextStyle(
color: Colors.white,
),
),
),
),
),
],
),
],
),
));
// ignore: non_constant_identifier_names
void ForgotPassword() async
setState(()
isLoginPressed = true;
);
try
await _auth.sendPasswordResetEmail(email: email.text);
setState(()
isLoginPressed = false;
);
Fluttertoast.showToast(
msg: 'email sent successfully!!',
textColor: Colors.black,
backgroundColor: Colors.white);
showSuccessDialog(context, "email Sent",
'An email has been sent to your registered email id for resetting password',
()
setState(()
forgotPassword = false;
);
Navigator.pop(context);
);
catch (e)
setState(()
isLoginPressed = false;
);
Fluttertoast.showToast(
msg: 'Please provide correct email',
textColor: Colors.black,
backgroundColor: Colors.white);
print(e);
Widget googleSignInButton()
return GestureDetector(
onTap: ()
performGoogleLogin();
,
child: Center(
child: CircleAvatar(
radius: 35.0,
backgroundImage: AssetImage("assets/google.png"),
),
),
);
void performGoogleLogin() async
setState(()
isLoginPressed = true;
);
FirebaseUser user = await _authMethods.signInWithGoogle();
if (user != null)
authenticateUser(user);
setState(()
isLoginPressed = false;
);
void performLogin() async
setState(()
isLoginPressed = true;
);
FirebaseUser user = await _authMethods.signIn(email, password);
if (user != null)
authenticateUser(user);
setState(()
isLoginPressed = false;
);
void authenticateUser(FirebaseUser user)
_authMethods.authenticateUser(user).then((isNewUser)
setState(()
isLoginPressed = false;
);
if (isNewUser)
_authMethods.addDataToDb(user).then((value)
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context)
return HomeScreen();
));
);
else
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context)
return HomeScreen();
));
);
此代码为两个用户显示相同的主页。如何根据用户转换此代码以显示 2 个不同的主页? 更新:需要检查来自 firebase db 的字段,然后根据字段内的值将它们重定向到不同的页面。
【问题讨论】:
【参考方案1】:有多种方法可以做到这一点。我建议使用包含用户状态的StreamProvider
(来自Provider package
)。例如,您可以使用枚举:
enum UserState
FIREBASE_AUTH,
GOOGLE
当用户使用特定方法登录时,您向流中添加一个事件,该事件将更新提供程序,从而根据流的值更新屏幕。
如果您想在应用程序的其他地方使用用户身份验证状态,我也会采用这种方法,您可以轻松访问它。
如果这有帮助或者我误解了你,请告诉我!
【讨论】:
你能建议修改我的代码吗?会有帮助的 我不确定我是否有足够的空间来编写添加此功能所需的所有代码,但我会尝试为您配备所需的资源。所以你需要有一个流来保存用户的状态,这样你才能为他们显示正确的屏幕。您可以通过创建一个具有全局流的类来做到这一点,您可以在StreamProvider
中调用它。从这里您可以使用Provider.of<UserState>(context);
访问该值。您可以在此处找到有关提供商的更多信息:pub.dev/packages/provider。以上是关于颤振:如何显示用户特定的页面?的主要内容,如果未能解决你的问题,请参考以下文章