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

时间:2018-09-28 06:18:17

标签: dart flutter

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

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

但是当我在details.dart中按下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),
        ],
      ),),
    );
  }
}

6 个答案:

答案 0 :(得分:5)

简单说个例子

class Animals
{
  var animalList = ['dog','cat','cow'];

  // function for printing the list of animals

  void animalListPrinter(){
    for(var animal in animalList){
        print(animal);

     }
  }
}

将上述函数调用到另一个类

class ShowingAnimalList extends StatelessWidget {
     final Animals ani= new Animals();
     @override
     Widget build(BuildContext context) {
       return GestureDetector(
         onTap: ani.animalListPrinter(),
       );
  }
}
<块引用>

您可以从父类中调用任何具有此功能的 Widget

答案 1 :(得分:3)

您必须小心要执行的操作,因为您可能正在访问未装载的页面/小部件。假设您做一个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"),
        ),
      ),
    );
  }
}

答案 2 :(得分:2)

我们可以像下面一样轻松访问它。

className().MethodName(),

答案 3 :(得分:0)

在DetailsPage中导入HomePage类,并从中创建一个新实例,然后在公共实例中调用所需的方法。

答案 4 :(得分:0)

您可以创建另一个logout()函数,并提供home的上下文以推回登录屏幕/主屏幕,对我来说是这样的:

ZIO.fromTry

答案 5 :(得分:0)

我们可以帮忙实例制作下面给出的实例

var objectName = new ClassName()

注意:我们可以像这个例子一样使用一个空的构造函数。

 class Student{
void female(){
print('This is female method');
}
void male(){
print('This is malemethod'); }
}

第一步: var _instance1 = new Student();这里空的构造函数没关系。

step2:_instance1.male();调用我们想要的方法_instance1。