Flutter:InheritedWidget内部的对象无法更改值

时间:2018-11-04 09:16:59

标签: flutter

我对InheritedWidget有疑问。由于我的应用程序中的大多数页面都使用了用户对象,因此我创建了一个名为UserProvider的InheritedWidget类,因此无需沿着小部件树传递用户对象。在我尝试注销并用另一个用户登录之前,它工作正常。用户仍然是旧的。我做了一些研究,似乎InheritedWidget类中的值无法更改。有一种方法可以重写它,这样我就可以利用InheritedWidget并仍然能够更改用户对象的值?

UserProvider类:     UserProvider类扩展了InheritedWidget {       UserProvider({Key key,Widget child,this.user}):超级(key:key,child:child);       最终用户;

 /* @override
  bool updateShouldNotify(InheritedWidget oldWidget) => true;
*/

  @override
  bool updateShouldNotify(UserProvider oldWidget) {
    return user != oldWidget.user;
  }

  static UserProvider of(BuildContext context) {
    return (context.inheritFromWidgetOfExactType(UserProvider) as UserProvider);
  }
}

首页类:

class HomePage extends StatefulWidget {
  HomePage({this.auth, this.onSignedOut,this.userId});
  final BaseAuth auth;  
  final VoidCallback onSignedOut;
  final String userId;

  @override
  _HomePageState createState() => _HomePageState();

}


class _HomePageState extends State<HomePage> {

  String _userName;
  String _userEmail;
  String _userPicURL;

  User currentUser;

  void _signOut() async {
    try {
      await widget.auth.signOut();
      widget.onSignedOut();      

    } catch (e) {
      print(e);
    }
  }

    @override
  void initState() {
  super.initState();  

    currentUser = User(widget.userId);
    currentUser.loadUserData();
...

@override
Widget build(BuildContext context) {
return UserProvider(
    user: currentUser,

...

LoginPage类:

class LoginPage extends StatefulWidget {
  LoginPage({this.auth, this.onSignedIn});
  final BaseAuth auth;
  final VoidCallback onSignedIn;

  @override
  //_LoginPageState createState() => _LoginPageState();
  State<StatefulWidget> createState() => _LoginPageState();
}


enum FormType {
  login,
  register
}

class _LoginPageState extends State<LoginPage> {

  final formKey = new GlobalKey<FormState>();

  String _uid;
  String _email;
  String _password;
  String _birthday;
  String _fullname;
  FormType _formType = FormType.login;

  bool validateAndSave() {
    final form = formKey.currentState;
    if (form.validate()) {
      form.save();
      return true;
    } else {
      return false;
    }
  }


void _addData(String email, String fullname, String birthday) async {



  _uid = await widget.auth.currentUser();
  Firestore.instance.runTransaction((Transaction transaction) async{


  Firestore.instance.collection("Users").document(_uid).setData(
    {
      "id": _uid,
      "email" : email,
      "fullname": fullname,
      "birthday" : birthday
    }); 
  });
}


   void validateAndSubmit() async{
    final form = formKey.currentState;
    if (validateAndSave()) {
      try {
        if (_formType == FormType.login) { 
          String userId = await widget.auth.signInWithEmailAndPassword( _email.trim(),  _password.trim());
        } else {

          String userId = await widget.auth.createUserWithEmailAndPassword( _email.trim(),  _password.trim());
          _addData(_email, _fullname, _birthday);          
        }
        widget.onSignedIn();
      }
      catch (e)
       {
         print('Error: $e');
       }
    } else {
      print('form is invalid');
    }
  }

  void moveToRegister () {
    formKey.currentState.reset();
    setState(() {
          _formType = FormType.register;          
        });
  }

  void moveToLogin () {
    formKey.currentState.reset();
    setState(() {
          _formType = FormType.login;

        });
  }



  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Login"),
        backgroundColor:  const Color(0xFF86d2dd),
      ),
      body: new Container(
        padding: EdgeInsets.all(16.0),
        child: new Form(
          key: formKey,
          child: new Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: buildInputs() + buildSubmitButtons(),
          )
        )
      )
    );
  }  

  List<Widget> buildInputs() {    
    if (_formType == FormType.login) {    
      return [

             new TextFormField(
                decoration: new InputDecoration(labelText: "Email"),
                validator: (value) => value.isEmpty ? 'Email can\'t be empty' : null,
                onSaved: (value) => _email = value,
              ),      
               new TextFormField(
                decoration: new InputDecoration(labelText: "Password"),
                obscureText: true,
                validator: (value) => value.isEmpty ? 'Password can\'t be empty' : null,
                onSaved: (value) => _password = value,                
              ),      
      ];
    } else {
      return [

             new TextFormField(
                decoration: new InputDecoration(labelText: "Email"),
                validator: (value) => value.isEmpty ? 'Email can\'t be empty' : null,
                onSaved: (value) => _email = value,
              ),      
               new TextFormField(
                decoration: new InputDecoration(labelText: "Password"),
                obscureText: true,
                validator: (value) => value.isEmpty ? 'Password can\'t be empty' : null,
                onSaved: (value) => _password = value,                
              ),       
               new TextFormField(
                decoration: new InputDecoration(labelText: "Name "),
                validator: (value) => value.isEmpty ? 'Name can\'t be empty' : null,
                onSaved: (value) => _fullname = value,                
              ),                
               new TextFormField(
                decoration: new InputDecoration(labelText: "Birthday (MM/DD)"),
                validator: (value) => value.isEmpty ? 'Birthday can\'t be empty' : null,
                onSaved: (value) => _birthday = value,                
              ),   



      ];
    }
  }

  List<Widget> buildSubmitButtons() {
    if (_formType == FormType.login) {    
      return [

        new RaisedButton(
          child: new Text('Login', style: new TextStyle(fontSize: 20.0)),
          onPressed: validateAndSubmit,
        ),
        new FlatButton(
          child: new Text('Create an account', style: new TextStyle(fontSize: 20.0)),
          onPressed: moveToRegister,
          )     
      ];
    } else {
      return [

        new RaisedButton(
          child: new Text('Create an account', style: new TextStyle(fontSize: 20.0)),
          onPressed: validateAndSubmit,
        ),
        new FlatButton(
          child: new Text('Have an account? Login', style: new TextStyle(fontSize: 20.0)),
          onPressed: moveToLogin,
          )     
      ];
    }
  }

}

1 个答案:

答案 0 :(得分:0)

我自己正在尝试InheritedWidget。阅读https://stackoverflow.com/a/51912243/7050833之后,我将尝试将UserProvider放在MaterialApp上方。

[3, 5, "a", "b"]