我已经创建了一个主页,用户可以登录该应用程序,在下一个屏幕上,用户可以看到他们的个人资料信息(只有个人资料名称)和下一个是他们的注销按钮.用户可以使用"注销"按钮从应用程序注销.但这对我不起作用.

我想通过按Details.dart中的signout按钮从main.dart调用signout方法(这两个类位于不同的文件中)

但是当我详细地按下签到按钮时,dart 什么也没react !

代码如下:

main.dart

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 '细节.飞奔';

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),),
      ),
    );
  }
}

细节.飞奔

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),
        ],
      ),),
    );
  }
}

推荐答案

您必须小心您正在try 执行的操作,因为您可能正在访问未挂载的页面/小部件.想象一下你做了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"),
        ),
      ),
    );
  }
}

如果您仍然想要调用另一个页面中的函数,并且您确定该页面已经挂载(您已经执行了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"),
        ),
      ),
    );
  }
}

Flutter相关问答推荐

为什么小部件会在其父文件中重建,但放在单独文件中时却不会重建?

ProviderContainer和GoRouter

DART 3.3:为什么扩展类型不起作用?

从底部开始固定,然后使其可拖曳Flutter

在setState之后,Ffltter ListView.Builder未更新

Firebase动态链接已弃用,不应在新项目中使用.Flutter 替代方案

如何在容器小部件中的图像旁边添加文本?

从图标启动器打开时,VSCode未检测到Web设备

Flutter飞溅屏幕即使在修改后仍显示默认徽标和背景色

ScaffoldMessenger 在等待键下方不起作用

文本溢出文本框 - Flutter

用户文档 ID 与 Firestore 中的用户 ID 相同

#Flutter/Riverpod - 使用 AsyncNotifier 时是否可以仅调用错误?

当项目较少时收缩列表视图

Flutter sliver 持久化

在 Flutter 中使用 HardwareKeyboard 时所有键都没有响应

无法在Flutter 图像小部件中打开大尺寸(500MB)图像

如何在 flutter 中制作这种类型的扩展瓦片

如何在 flutter 中制作这种类型的扩展瓦片

我一直在try 创建按钮以导航到第二页,但不知何故 RaisedButton 功能无法正常工作