【问题标题】:Provider method returns null when called from another pageProvider 方法在从另一个页面调用时返回 null
【发布时间】:2020-06-07 16:05:51
【问题描述】:

我有一个应用程序,我在其中记录我的用户,将其保存在提供程序状态中,然后尝试在不同的页面中获取保存的状态,但它一直返回 null。

我的代码:

main.dart:

void main() => runApp(
    MultiProvider(
        providers: [
          ChangeNotifierProvider(create: (_) => AuthenticationProvider())
        ],
        child:MyApp()
    )
);

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.indigo,
        primaryColor: Colors.indigo,
        brightness: Brightness.light,
        scaffoldBackgroundColor: Colors.white
      ),
      home: Consumer<AuthenticationProvider>(
        builder: (context, AuthenticationProvider user, _) {
          return showScreen(user);
        },
      ),
      routes: {
        '/login': (context) => Login(),
        '/home': (context) => Home(),
        '/extrato': (context) => Extrato(),
        '/atendimento': (context) => AtendimentoPage(),
        '/informacoes': (context) => Informacoes(),
        '/manual': (context) => Manual(),
        '/recarga': (context) => RecargaPage(),
        '/splah': (context) => Splash()
      }
    );
  }
}

Widget showScreen(user) {
  switch (user.status) {
    case Status.Uninitialized:
      return Splash();
    case Status.Unauthenticated:
    case Status.Authenticating:
      return Login();
    case Status.Authenticated:
      return Home();
  }
}

authentication_provider.dart:

class AuthenticationProvider extends ChangeNotifier {

  AuthenticationProvider(){

  }

  PontoVenda _user;

  PontoVenda get user => _user;

  Status _status = Status.Uninitialized;

  Status get status => _status;

  Future login(String login, String senha) async {
    try {

      final response = await AuthenticationService().authenticateUser(login, senha);

      final mapResponse = _parseLogin(response);

      _status = Status.Authenticated;
      _user = await PontoVendaService().fetchPontoVenda(mapResponse["token"]);

      print(_user.data);

      notifyListeners();

      return user;

    } catch(e) {
      print(e);
      _status = Status.Unauthenticated;
      notifyListeners();
    }
  }

  Map<String, dynamic> _parseLogin(response) {
    return json.decode(response.body);
  }

  void logOut() async {
    _user = null;
    _status = Status.Unauthenticated;
    notifyListeners();
  }

}

home.dart(我试图获取用户状态数据的地方):

class Test extends StatelessWidget {
  final ExtratoService _extratoService = ExtratoService();
  final AtendimentoService _atendimentoService = AtendimentoService();

  @override
  Widget build(BuildContext context) {
    // Trying here
    final testingStuff = Provider.of<AuthenticationProvider>(context);

    print(testingStuff.user);

    return ListView(
      children: <Widget>[
        Stack(
          alignment: Alignment.center,
          children: <Widget>[
            Image(image: AssetImage("assets/images/box-03.png"),height: 300, width: double.infinity, fit: BoxFit.cover,),
            Container(
              height: 300,
              color: Colors.black54.withOpacity(0.4),
            ),
            Positioned(
                bottom: 60,
                child: Container(
                    padding: EdgeInsets.all(20),
                    child: Column(
                      children: <Widget>[
                        Text('Bem vinda(o), fulano', style: TextStyle(color: Colors.white, fontSize: 18)),
                        Text('Seu saldo atual', style: TextStyle(color: Colors.white, fontSize: 18)),
                        Text('R\$300.00', style: TextStyle(color: Colors.white, fontSize: 35),)

                      ],
                    )
                )
            )
          ],
        ),
        _previewCards('Últimas recargas', context, _ultimasRecargas(context)),
        _previewCards('Últimos atendimentos', context, _ultimosAtendimentos(context))
      ],
    );
  }

  ...
}

编辑:

登录.dart

class Login extends StatefulWidget {

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

class _LoginState extends State<Login> {

  @override
  void initState() {
    super.initState();
    SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values);
  }

  final _formKey=GlobalKey<FormState>();

  final _tLogin = TextEditingController(text: "3m3");

  final _tSenha = TextEditingController(text: "601733");

  bool _showProgress = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _body(),
    );
  }

  Widget _body() {
    return Form(
      key: _formKey,
      child: Container(
        padding: EdgeInsets.all(16),
        child: ListView(
          children: <Widget>[
            _img(),
            AppText(
              "Login",
                "Digite o login",
                controller: _tLogin,
                validator: _validateLogin,
            ),
            SizedBox(height: 20),
            AppText("Senha",
                "Digite a senha",
                controller: _tSenha,
                password: true,
                validator: _validateSenha,
            ),
            SizedBox(
                height: 20
            ),
            AppButton(
              "Entrar",
              onPressed: _onClickLogin,
              showProgress: _showProgress,
            )
          ],
        ),
      ),
    );
  }

  Widget _img() {
    return Image.asset("assets/images/logo.png");
  }

  void _onClickLogin() async {
    if(!_formKey.currentState.validate()) {
      return;
    }

    setState(() {
      _showProgress = true;
    });

    final user = await AuthenticationProvider().login(_tLogin.text, _tSenha.text);
PontoVendaProvider().getPontosVendasList(user.token);

    push(context, Home(), replace: true);

    setState(() {
      _showProgress = false;
    });
  }

  String _validateLogin(String text) {
      if (text.isEmpty) {
        return "Digite o login";
      }
      return null;
    }

  String _validateSenha(String text) {
    if (text.isEmpty) {
      return "Digite a senha";
    }
    if(text.length < 3) {
      return "A senha precisa ter pelo menos 3 digitos";
    }
    return null;
  }

}

我不确定到底发生了什么。我正在尝试获取应该保存在身份验证提供程序状态中的用户,但它只返回 null。我将我的 ChangeNotifier 放在小部件树的上方,但它仍然不起作用。有人可以帮忙吗?

【问题讨论】:

  • 您在authentication_provider.dart 中调用login 方法的部分在哪里?
  • 你在哪里得到空值?
  • @SelimKundakçıoğlu 我没有在我的authentication_provider 中调用login 方法,我在login.dart 中调用它,这是包含登录表单的页面,我将更新问题也提供这部分代码。
  • @Kahou 当我尝试访问home.dart 中的用户属性时,我得到了null,我使用Provider.of&lt;AuthenticationProvider&gt;(context),当我打印它时它返回null。

标签: flutter dart provider


【解决方案1】:

我发现我做错了什么。 我的错误是尝试使用 AuthenticationProvider 类中的 login 方法而不是启动提供程序,因此提供程序从未更新用户状态。 更改这行代码:AuthenticationProvider().loginProvider.of&lt;AuthenticationProvider&gt;(context).login 修复它。

【讨论】:

    猜你喜欢
    • 2016-08-07
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-10
    • 1970-01-01
    • 2018-09-20
    相关资源
    最近更新 更多