简体   繁体   English

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

[英]How to call method from another class in 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.用户可以使用退出按钮从应用程序退出。但这对我不起作用。

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 按钮从 main.dart 调用 signOut 方法(两个类都在不同的文件中)

But when i press signOut Button in details.dart nothing happens!但是当我在 details.dart 中按下 signOut 按钮时,什么也没有发生!

And code is given below:代码如下:

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详细信息.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),
        ],
      ),),
    );
  }
}

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(...)) .想象一下你做了一个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.因此,您确定您正在调用类的活动实例。

Here is an example of what you could use passing around the Business object.以下是您可以使用的传递 Business 对象的示例。 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.如果您使用其他模式,如 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"),
        ),
      ),
    );
  }
}

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.如果您仍想调用另一个 Page 中的函数,并且您确定该页面已安装(您执行的是push而不是pushReplacement ),您可以执行以下操作。 (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"),
        ),
      ),
    );
  }
}

It is simple let me explain with an example很简单让我用一个例子来解释

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

  // function for printing the list of animals

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

     }
  }
}

Calling the above function to another class将上述函数调用到另一个类

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

You can call any Widget with this from the parent class你可以从父类调用任何小部件

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

className().MethodName(),

you can create another logout() function and give context of home to push back to sign in screen/home screen , works for me as :您可以创建另一个 logout() 函数并提供 home 上下文以推回登录屏幕/主屏幕,对我来说如下:

      logout() async {
        await googleSignIn.signOut();
        Navigator.push(context, MaterialPageRoute(builder: (context) => Home()));
      }

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

We can take help instance Make instance given below我们可以通过下面给出的帮助实例Make 实例

var objectName = new ClassName(<constructor_arguments>) var objectName = new ClassName(<constructor_arguments>)

Note : We can use an empty constructor like this example.注意:我们可以像这个例子一样使用一个空的构造函数。

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

step1: var _instance1 = new Student();第一步: var _instance1 = new Student(); here empty constructor it dos't matter.这里空的构造函数没关系。

step2 : _instance1.male();第二步:_instance1.male(); Call method _instance1 what we want.调用方法 _instance1 我们想要什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从 flutter 和 dart 中的另一个 class 调用一个 class 中的方法 - Call a method in one class from another class in flutter and dart Dart & Flutter:如何在另一个 class 中调用 class 方法 - Dart & Flutter: How to call for a class method inside another class 如何在另一个文件 dart 中调用类方法 - How to call class method in another file dart 从 Flutter 中的另一个 dart 文件在有状态小部件 class 下使用 SetState 方法调用 void - Call void with SetState method under stateful widget class from another dart file in Flutter 如何访问一个 class 中的方法并在 flutter 中的另一个类方法中调用它(飞镖) - How to access methods in one class an call it in another classes method in flutter (dart) 如何从另一个Dart文件中调用有状态的widget(具有表单)方法?-Flutter - How to Call stateful widget(have form) method from another dart file?- Flutter Flutter:如何从另一个 class 调用方法? - Flutter: how can I call method from another class? 如何从另一个文件导入 class 以在 Dart/Flutter 中调用 Future - How do you import a class from another file to call a Future in Dart/Flutter Flutter dart 调用超级 class 方法的超级 - Flutter dart call super of super class method 如何从 Flutter 中的 Android java Activity 调用 Dart 方法? - How to call a Dart method from an Android java Activity in Flutter?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM