我的用户登录时如何使用提供商通知?

How to use provider notification when my user logs in?

我是 flutter 和 provider 的新手。我只想在用户登录后从登录更改为主页小部件。我有一个包装器小部件,如果它被更改,它会监听用户模型,并自动显示身份验证小部件或主页小部件。下面的代码不会在我登录后通知包装器用户不为空。我不知道这是正确的使用方法,但我希望你能帮助我。

//main.dart

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<User>.value(
      value: User(),
      child: MaterialApp(),
        home: Wrapper(),
      ),
    );
  }
}

//wrapper.dart

class Wrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final user = Provider.of<User>(context);
    //return either home or authenticate widget
    print(user);
    if (user == null) {
      return Authenticate();
    } else {
      return Home();
    }
  }
}

//authenticate.dart

class Authenticate extends StatefulWidget {
  @override
  _AuthenticateState createState() => _AuthenticateState();
}

class _AuthenticateState extends State<Authenticate> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Signin(),
    );
  }
}

class Signin extends StatefulWidget {
  @override
  _SigninState createState() => _SigninState();
}

class _SigninState extends State<Signin> {
  final AuthService _auth = AuthService();
  @override
  Widget build(BuildContext context) {
    return Container(
      child: MaterialButton(
          onPressed: () async {
            if (_formKey.currentState.validate()) {
              dynamic result = await _auth.login(username, password);
            }
          },
      )
    )



//auth.dart

class AuthService {

  static const endpoint = 'http://192.168.254.100:8000';

  var client = new http.Client();

  Future login(String user, String password) async {
    try {
      var response = await client.get('$endpoint/rest_login/?username=test&password=test');

      return User.fromJson(json.decode(response.body));

    } catch (e) {
      return null;
    }
  }
}

//user.dart

class User with ChangeNotifier {
  int id;
  String name;
  String username;
  String email;
  String session;

  User({this.id, this.name, this.username, this.email, this.session});

  User.initial()
      : id = 0,
        name = '',
        username = '',
        email = '',
        session = '';

  User.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    name = json['name'];
    username = json['username'];
    email = json['email'];
    session = json['session'];
    notifyListeners();
  }
}

ChangeNotifierProvider的使用方式为:

Widget create(BuildContext context) {
  return ChangeNotifierProvider<ModelClass>(
    builder: (context) => ModelClass(auth: auth),
    child: Consumer<ModelClass>(
      builder: (context, model, _) => View(model: model),
    ),
  );
}

按照上面的逻辑:

return ChangeNotifierProvider<User>(
      builder: (context) => User(auth: auth),
      child: Consumer<User>(
        builder: (context, user, _) =>
            YourView(user: user),
      ),
    )

您需要更改您的 MyApp 小部件。

如果有帮助请告诉我。谢谢

User.fromJson 是构造函数。不要在那里调用 notifyListeners()

您必须为模型指定 Consumer 个小部件,以便在模型调用 notifyListeners() 时重建它。

这可能有帮助,

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:provider/provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<UserModel>.value(
      value: UserModel(),
      child: MaterialApp(
        home: Wrapper(),
      ),
    );
  }
}

//wrapper.dart

class Wrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    //return either home or authenticate widget
    return Consumer<UserModel>(
      builder: (context, userModel, child) {
        if (userModel.user == null) {
          return Authenticate();
        } else {
          return Home();
        }
      },
    );
  }
}

//authenticate.dart

class Authenticate extends StatefulWidget {
  @override
  _AuthenticateState createState() => _AuthenticateState();
}

class _AuthenticateState extends State<Authenticate> {
  @override
  Widget build(BuildContext context) {
    return Material(
      child: SignIn(),
    );
  }
}

class SignIn extends StatefulWidget {
  @override
  _SignInState createState() => _SignInState();
}

class _SignInState extends State<SignIn> {
  final AuthService _auth = AuthService();

  @override
  Widget build(BuildContext context) {
    return Container(
      child: MaterialButton(
        child: Text("Login"),
        onPressed: () async {
          final user = await _auth.login("Name", "Password");
          Provider.of<UserModel>(context, listen: false).user = user;
        },
      ),
    );
  }
}

//auth.dart
class AuthService {
  static const endpoint = 'http://192.168.254.100:8000';

  var client = new http.Client();

  Future<User> login(String user, String password) async {
    // Use your logic and return User or null
    return User(name: "Name");
  }
}

//user.dart
class User {
  int id;
  String name;
  String username;
  String email;
  String session;

  User({this.id, this.name, this.username, this.email, this.session});

  User.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    name = json['name'];
    username = json['username'];
    email = json['email'];
    session = json['session'];
  }
}

//home.dart
class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text("Home Page"),
      ),
    );
  }
}

//user_model.dart
class UserModel extends ChangeNotifier {
  User _user;

  User get user => _user;

  set user(User value) {
    _user = value;

    //here the model value changes. you can call 'notifyListeners' to notify all the 'Consumer<UserModel>'
    notifyListeners();
  }
}