我创建了一个主页,从该用户可以登录该应用程序,然后在下一个屏幕中,用户可以看到其个人资料信息(仅个人资料名称),并在其下方是“退出”按钮。用户可以使用signOut按钮从应用程序中注销。但这对我不起作用。
我想通过在details.dart中按signOut按钮从main.dart调用signOut方法(两个类都在不同的文件中)
但是当我在details.dart中按下signOut Button时,什么也没有发生!
代码如下:
主镖
import 'dart:async'; import 'package:flutter/material.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:google_sign_in/google_sign_in.dart'; import 'details.dart'; void main() => runApp(new MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( theme: new ThemeData( primarySwatch: Colors.blue, ), debugShowCheckedModeBanner: false, home: new MyHomePage(), ); } } class MyHomePage extends StatefulWidget { @override MyHomePageState createState() => MyHomePageState(); } class MyHomePageState extends State<MyHomePage> { final FirebaseAuth firebaseAuth = FirebaseAuth.instance; final GoogleSignIn googleSignIn = GoogleSignIn(); static bool _LoginButton = true; void signOut(){ googleSignIn.signOut(); setState((){ _LoginButton = true; }); print(_LoginButton); print("User Signed Out"); } Future<FirebaseUser> _signIn() async{ if(_LoginButton==true){ setState((){ _LoginButton=false; }); GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn(); GoogleSignInAuthentication googleSignInAuthentication = await googleSignInAccount.authentication; FirebaseUser firebaseUser = await firebaseAuth.signInWithGoogle(idToken: googleSignInAuthentication.idToken, accessToken: googleSignInAuthentication.accessToken); print("Username is "+firebaseUser.displayName); setState((){ _LoginButton = true; }); Navigator.push(context, MaterialPageRoute(builder: (context) => details(firebaseUser.displayName,signOut))); return firebaseUser; } } bool _LoginButtonBool(){ return _LoginButton; } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text("Google auth with firebase"),), body: Center( child: _LoginButtonBool()?Container( child: Column( mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[ MaterialButton(onPressed: _LoginButtonBool() ? () => _signIn().then((FirebaseUser firebaseuser ) =>print(firebaseuser)).catchError((e) => print(e)): null, child: Text("Login"),color: Colors.orange,), ], ), ):CircularProgressIndicator(backgroundColor: Colors.greenAccent.withOpacity(0.01),), ), ); } }
details.dart
import 'package:flutter/material.dart'; import 'package:flutter_auth/main.dart'; class details extends StatelessWidget { String name; final Function callback; details(this.name,this.callback); @override Widget build(BuildContext context) { return Scaffold( body:Center(child: Column( mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[ Text(name), MaterialButton(onPressed: () => callback, child: Text("Log out"),color: Colors.orange), ], ),), ); } }
您必须谨慎对待尝试做的事情,因为您可能正在访问未装载的页面/小部件。想象你做一个pushReplacement(new MaterialPageroute(...))。前一页在树中不再可用,因此您无法访问它或它的任何方法。
pushReplacement(new MaterialPageroute(...))
除非您在树中有明确的父子关系,否则应将逻辑抽象为外部或业务逻辑类。因此,您可以确定正在调用类的活动实例。
这是您可以使用的围绕Business对象传递的示例。如果使用其他模式(例如BLOC,ScopedModel,Streams等)会更好。但是为了简单起见,我认为这应该足够了。
import "package:flutter/material.dart"; void main() { runApp(MyApp(new Logic())); } class Logic { void doSomething() { print("doing something"); } } class MyApp extends StatelessWidget { final Logic logic; MyApp(this.logic); @override Widget build(BuildContext context) { return new MaterialApp( home: new HomePage(widget.logic), ); } } class HomePage extends StatelessWidget { final Logic logic; HomePage(this.logic); @override Widget build(BuildContext context) { return Scaffold( body: Center( child: FlatButton( onPressed: () { Navigator.of(context).pushReplacement( MaterialPageRoute( builder: (context) => AnotherPage(logic), ))}, child: Text("Go to AnotherPage"), ), ), ); } } class AnotherPage extends StatelessWidget { final Logic logic; AnotherPage(this.logic); @override Widget build(BuildContext context) { return Scaffold( body: Center( child: FlatButton( onPressed: logic.doSomething, child: Text("Press me"), ), ), ); } }
如果您仍然想在另一个Page中调用一个函数,并且确定该页面已装入(您已经完成了push而不是的操作pushReplacement),则可以执行以下操作。(小心轻放)
push
pushReplacement
class HomePage extends StatelessWidget { HomePage(); void onCalledFromOutside() { print("Call from outside"); } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: FlatButton( onPressed: () { Navigator.of(context).push( MaterialPageRoute( builder: (context) => AnotherPage(onCalledFromOutside), ))}, child: Text("Go to AnotherPage"), ), ), ); } } class AnotherPage extends StatelessWidget { final Function callback AnotherPage(this.callback); @override Widget build(BuildContext context) { return Scaffold( body: Center( child: FlatButton( onPressed: callback, child: Text("Press me"), ), ), ); } }