如何从Flutter(Dart)中的另一个类调用方法? [英] How to call method from another class in Flutter(Dart)?

查看:1119
本文介绍了如何从Flutter(Dart)中的另一个类调用方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了一个主页,该用户可以登录该应用程序,然后在下一个屏幕中,用户可以看到其个人资料信息(仅个人资料名称),并在其下方是退出按钮。用户可以使用signOut按钮从应用程序中注销。但这对我不起作用。

I have created an Homepage and from that user can sign in for the app and in the next screen user can see their profile info(Only profile name) and under that their is signOut button. User can signOut from the app using signOut button.But it's not working for me.

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

I want to call signOut method from main.dart by pressing signOut button in details.dart(both the classes are in different file)

但是当我在details.dart中按下signOut Button时,什么也没发生!

But when i press signOut Button in details.dart nothing happens!

代码如下:

main.dart

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

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(...))。前一页在树中不再可用,因此您将无法访问它或它的任何方法。

You must be careful with what you are trying to do because you might be accessing a page/widget that is not mounted. Imagine you do a pushReplacement(new MaterialPageroute(...)). The previous page is no longer available in the tree so you can't access it nor any of its methods.

除非您在树中有明确的父子关系,您应该将逻辑抽象为外部或业务逻辑类。因此,您可以确定正在调用类的活动实例。

Unless you have a clear parent child relationship in your tree, you should abstract away your logic to external or business logic classes. Thus you are sure that you are calling active instances of your classes.

这里是可用于传递Business对象的示例。如果您使用其他模式(例如BLOC,ScopedModel,Streams等)会更好。但是为了简单起见,我认为这应该足够了。

Here is an example of what you could use passing around the Business object. It would be even better if you use other patterns like BLOC, ScopedModel, Streams, etc. But for the sake of simplicity I think this should be enough.

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 ),您可以以下。 (小心处理)

If you still want to call a function in the other Page and you are sure the page is mounted (you have done a push instead of a pushReplacement) you could do the following. (handle with care)

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(Dart)中的另一个类调用方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆