Flutter: объекты внутри InheritedWidget не могут изменить значение - PullRequest
0 голосов
/ 04 ноября 2018

У меня вопрос по InheritedWidget. Поскольку большинство страниц в моих приложениях использовали пользовательский объект, поэтому я создал класс InheritedWidget с именем UserProvider, поэтому мне не нужно передавать пользовательский объект по дереву моего виджета. Работает нормально, пока я не попытался выйти из системы и войти под другим пользователем Пользователь остается старым. Я немного изучаю, и кажется, что значение внутри класса InheritedWidget не может быть изменено. Есть ли способ переписать его, чтобы я мог воспользоваться InheritedWidget и все еще иметь возможность изменять значение пользовательского объекта?

Класс UserProvider: класс UserProvider extends InheritedWidget { UserProvider ({Key key, Widget child, this.user}): super (ключ: ключ, 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);
  }
}

Класс HomePage:

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 голосов
/ 11 ноября 2018

Я сам экспериментирую с InheritedWidget. После прочтения https://stackoverflow.com/a/51912243/7050833 я бы попытался разместить UserProvider над MaterialApp.

UserProvider(child: MaterialApp(...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...