首页 文章

如何在Flutter(Dart)中从另一个类调用方法?

提问于
浏览
1

我创建了一个主页,并且该用户可以登录该应用程序,在下一个屏幕中,用户可以看到他们的 Profiles 信息(仅限 Profiles 名称),并在其下面是signOut按钮 . 用户可以使用signOut按钮从应用程序中签名 . 但它不适合我 .

我想通过在details.dart中按signOut按钮从main.dart调用signOut方法(两个类都在不同的文件中)

但是,当我在详细信息中按signOut Button时,没有任何反应!

代码如下:

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

2 回答

  • 2

    在DetailsPage中导入HomePage类并从中创建一个新实例,然后调用所需的方法(如果它是公共方法) .

  • 0

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

相关问题