如何从 Flutter(Dart) 中的另一个类调用方法?
Posted
技术标签:
【中文标题】如何从 Flutter(Dart) 中的另一个类调用方法?【英文标题】:How to call method from another class in Flutter(Dart)? 【发布时间】:2022-01-03 03:41:02 【问题描述】:我创建了一个主页,用户可以从该主页登录该应用,然后在下一个屏幕中,用户可以看到他们的个人资料信息(仅个人资料名称),并且在该页面下方是他们的退出按钮。用户可以使用注销按钮从应用程序中注销。但这对我不起作用。
我想通过按 details.dart 中的 signOut 按钮从 main.dart 调用 signOut 方法(两个类都在不同的文件中)
但是当我在 details.dart 中按下 signOut 按钮时没有任何反应!
代码如下:
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),
],
),),
);
【问题讨论】:
您是否尝试过使用回调? ***.com/questions/51029655/… 我尝试使用回调,但我收到一条错误消息:“此处的表达式的类型为 'void',因此无法使用。 在 details.dart 中:将 MaterialButton(onPressed: () => 回调更改为 MaterialButton(onPressed: () => callback(),尽管这不会解决您在这里尝试做的事情,但不会推送你回到登录屏幕。 @anmol.majhail 我不知道为什么,但这对我有用!!谢谢,如果你能解释一下,那对我来说会更好。 @yash1173 要执行一个函数,我们需要调用一个带括号的函数。你只是在引用没有执行它的函数。 【参考方案1】:您必须小心您正在尝试执行的操作,因为您可能正在访问未安装的页面/小部件。想象一下你做了一个pushReplacement(new MaterialPageroute(...))
。上一页在树中不再可用,因此您无法访问它,也无法访问它的任何方法。
除非您的树中有明确的父子关系,否则您应该将您的逻辑抽象为外部或业务逻辑类。因此,您确信您正在调用您的类的活动实例。
下面是一个可以用来传递业务对象的示例。如果你使用其他模式,如 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"),
),
),
);
【讨论】:
大家好,我该如何在 main.dart 的路线上使用参数? 好吧,你不能将参数传递给路由本身,但你可以将参数传递给你正在构建的小部件的构造函数(如上面的 bloc 参数)o 使用RouteSettings
作为@ rémi-rousselet 建议在***.com/questions/47419908【参考方案2】:
很简单,我举个例子来解释
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
【讨论】:
【参考方案3】:我们可以像下面这样轻松访问它。
className().MethodName(),
【讨论】:
【参考方案4】:您可以创建另一个 logout() 函数并提供主页上下文以推回登录屏幕/主屏幕,对我来说是:
logout() async
await googleSignIn.signOut();
Navigator.push(context, MaterialPageRoute(builder: (context) => Home()));
【讨论】:
【参考方案5】:在 DetailsPage 中导入 HomePage 类并从中创建一个新实例,然后调用您想要的方法(如果它是公共方法)。
【讨论】:
我确信它不会工作,因为我无法创建它的对象。【参考方案6】:我们可以帮忙实例制作下面给出的实例
var objectName = new ClassName(
注意:我们可以像这个例子一样使用一个空的构造函数。
class Student
void female()
print('This is female method');
void male()
print('This is malemethod');
第一步: var _instance1 = new Student();这里空的构造函数没关系。
第二步:_instance1.male();调用我们想要的方法_instance1。
【讨论】:
以上是关于如何从 Flutter(Dart) 中的另一个类调用方法?的主要内容,如果未能解决你的问题,请参考以下文章
将 API 数据从第 1 页传递到 Flutter 上的另一个 dart 页面
如何从另一个 dart 文件中调用有状态小部件(有表单)方法?- Flutter
如何使用 Dart / Flutter 中的列表从列表中删除重复元素?