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

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

问题描述

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

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 按钮时,什么也没有发生!

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

代码如下:

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

详细信息.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天全站免登陆