провайдер флаттера в чем разница между контекстом и контекстом - PullRequest
0 голосов
/ 09 июля 2020
```
import 'package:a_class_flutter/provider/ac_score/ac_score_provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provider/provider.dart';

class ACScoreView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => ACScoreProvider(),
      builder: (context, child) {
        return Stack(
          children: <Widget>[
            _topMenu(context),
          ],
        );
      },
    );
  }
}
// Important!
Widget _topMenu(BuildContext context) {
  return GestureDetector(
    onTap: () {
      context.read<ACScoreProvider>().showTopMenueStatus();
    },
    child: Container(
      width: double.infinity,
      height: double.infinity,
      color: Colors.red,
      child: Stack(
        children: <Widget>[
          Positioned(
            child: AnimatedOpacity(
              duration: Duration(microseconds: 100),
              opacity:
                  context.watch<ACScoreProvider>().needShowTopMenue ? 1.0 : 0.0,
              child: Container(
                width: double.infinity,
                height: ScreenUtil().setHeight(60),
                color: Colors.black,
              ),
            ),
          )
        ],
      ),
    ),
  );
}
```

Это мой код, который работает хорошо, но когда я пытаюсь изменить Widget _topMenu(BuildContext context) на Widget _topMenu(context), Flutter выдает ошибку:

The following NoSuchMethodError was thrown building Builder(dirty, dependencies: [_InheritedProviderScope<ACScoreProvider>]): Class 'StatelessElement' has no instance method 'watch'. Receiver: Instance of 'StatelessElement'. Tried calling: watch<ACScoreProvider>().The relevant error-causing widget was ChangeNotifierProvider<ACScoreProvider> package:a_class_flutter/…/ac_score/ac_score.dart:9.

Почему отсутствует BuildContext объявление могло вызвать эту ошибку? Нужно ли помещать каждый контекст в BuildContext?

1 Ответ

0 голосов
/ 09 июля 2020

От поставщика docs :

Самый простой способ прочитать значение - использовать методы расширения в [BuildContext]:

  • context.read<T>(), который возвращает T, не прослушивая его

Записывая только Widget _topMenu(context), параметр context выводится как dynamic context, а не BuildContext context, и, следовательно, вы это делаете нет метода расширения .read<T>(), который вы пытаетесь вызвать.

Если бы он находился внутри StatefulWidget, это не было бы проблемой, потому что у этого класса State есть экземпляр context (type BuildContext), поэтому для него может быть вызван метод расширения .read<T>().

...