我如何将变量传递给类并在其他屏幕上调用该变量而不重置它

时间:2019-05-21 11:48:51

标签: dart flutter

我希望能够从一个类中调用一个空变量,为它分配一个值并使其持久化,除了提供者等之外的任何东西都将是有帮助的,我不想再次检查整个应用程序来做一些事情,提供商等

注意:所有屏幕都是有状态的小部件

我尝试用空字符串创建一个类,并从另一个屏幕将值传递给它,但这似乎不起作用

import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';

class MethodA {

//  id(user, context){
//    var name =user.email;
//  }
 String identity;

 MethodA({this.iD});

  bool isLoggedIn() {
    if (FirebaseAuth.instance.currentUser() != null) {
      return true;
    } else {
      return false;
    }
  }

  Future<void> addUserA( userinfo) async {
    //this.iD=id;

    Firestore.instance
        .collection('user')
        .document('furtherinfo').collection(identity).document('Personal Info')
        .setData(userdoc)
        .catchError((e) {
      print(e);
    });
  }

每次我将参数传递给foo ='bar';

然后我将该类导入另一个屏幕,即屏幕9,foo自动设置为null,但是我希望foo为bar

2 个答案:

答案 0 :(得分:0)

我建议您使用Provider,因为这是我管理整个应用程序状态的最简单方法。 Flutter从小部件树顶部的一个组件开始,所以我将提供程序放在这里。

示例

void main() {runApp(MyApp());}

class MyApp extends StatelessWidget {
  MyApp();

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        StreamProvider<FirebaseUser>.value(
          stream: FirebaseAuth.instance.onAuthStateChanged, // Provider to manage user throughout the app.
        ),
      ],
      child: MaterialApp(
        title: 'My App',
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          primaryColor: Colors.green,
          primarySwatch: Colors.green,
          accentColor: Colors.yellow,
        ),
        home: MainPage(),
      ),
    );
  }
}

然后在您的课程中,您可以执行以下操作

class MethodAService with ChangeNotifier {
 String _identity = null;
 FirebaseUser _user = null;

 // constructor with the (new changes )
 MethodAService(FirebaseUser user){
      this._user  = user;
 }

  get identity => _identity ;

  setIdentity(String identity) {
    _identity = identity ;
    notifyListeners(); // required to notify the widgets of your change
  }
}

然后,当您想在应用程序中的任何地方使用它时,只需在构建方法中执行以下操作

 @override
  Widget build(BuildContext context) {
    final user = Provider.of<FirebaseUser>(context); // to get the current user
    final methodA = Provider.of<MethodAService>(context); // get your service with identity

   // now you can set the string using 
    methodA.setIdentity('new identity');

    // or just use it like this
    if(methodA.identity.isNotEmpty()){
      print(methodA.identity);
    }else{
       print('Identity is empty');
     }

    return ChangeNotifierProvider<MethodAService>(
            builder: (context) => MethodAService(user), // Your provider to manage your object, sending the Firebase user in


   child: loggedIn ? HomePage() : LoginPage(), );
  }

参考

Provider Package

Fireship 185 Provider

Great Youtube video explaining the code

更新评论

要获取用户uid,您只需执行user.uid

更改了上面的代码以适合

答案 1 :(得分:0)

我不确定将整个应用程序放在StreamProvider中是最佳选择。这意味着该应用将在每个流值上重建。

要使小部件在所有屏幕上都可用,您需要在MaterialApp中使用 TransitionBuilder

为避免外部依赖性,您还可以使用InheritedWidget

signed_user.dart

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';

class SignedUser extends InheritedWidget {
  final FirebaseUser user;

  SignedUser({@required this.user, @required Widget child})
      : super(child: child);

  @override
  bool updateShouldNotify(SignedUser oldWidget) => true;

  static SignedUser of(BuildContext context) =>
      context.inheritFromWidgetOfExactType(SignedUser);
}

my_transition_builder.dart

class MyTransitionBuilder extends StatefulWidget {
  final Widget child;

  const MyTransitionBuilder({Key key, this.child}) : super(key: key);

  @override
  _MyTransitionBuilderState createState() => _MyTransitionBuilderState();
}

class _MyTransitionBuilderState extends State<MyTransitionBuilder> {
  StreamBuilder<FirebaseUser> _builder;

  @override
  void initState() {
    super.initState();
    _builder = StreamBuilder<FirebaseUser>(
        stream: FirebaseAuth.instance.onAuthStateChanged,
        builder: (context, snapshot) {
          return SignedUser(
            child: widget.child,
            user: snapshot.data,
          );
        });
  }

  @override
  Widget build(BuildContext context) {
    return _builder;
  }
}

main.dart

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // this will make your inherited widget available on all screens of your app
      builder: (context, child) {
        return MyTransitionBuilder(child: child);
      },
      routes: {
        '/editAccount': (context) => new EditAccountPage(),
      },
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: MyHomePage(),
    );
  }
}

在edit_account_page.dart中使用

@override
  Widget build(BuildContext context) {
    var user = SignedUser.of(context).user;

    return Scaffold(
      body: FutureBuilder<DocumentSnapshot>(
          future: Firestore.instance.document('users/${user.uid}').get(),