Как правильно инициализировать будущее в провайдере флаттера - PullRequest
1 голос
/ 28 февраля 2020

, поэтому я пытаюсь создать список в своем провайдере из будущего вызова.

Пока у меня есть следующий класс ChangeNotifier ниже:

class MainProvider extends ChangeNotifier {
  List<dynamic> _list = <dynamic>[];
  List<dynamic> get list => _list;
  int count = 0;

  MainProvider() {
    initList();
  }

  initList() async {
    var db = new DatabaseHelper();

    addToList(Consumer<MainProvider>(
        builder: (_, provider, __) => Text(provider.count.toString())));

    await db.readFromDatabase(1).then((result) {
      result.forEach((item) {
        ModeItem _modelItem= ModeItem.map(item);

        addToList(_modelItem);
      });
    });
  }

  addToList(Object object) {
    _list.add(object);
    notifyListeners();
  }

  addCount() {
    count += 1;
    notifyListeners();
  }
}

Однако это что происходит всякий раз, когда я использую значение list :

  1. Я могу подтвердить, что моя функция initList выполняется правильно
  2. Исходное содержимое из доступное значение list - это виджет Text () , который я впервые вставил с помощью функции addToList , что означает, что в список на данный момент
  3. Когда я выполняю «Горячую перезагрузку», остальное содержимое списка теперь кажется

Примечания:

  1. Я использую значение list в виджете AnimatedList, поэтому я должен показать содержимое list
  2. Изначально кажется, что содержимое моего списка значение - только один элемент
  3. Мой список значение не отображается для автоматического обновления во время выполнения моего вызова Future
  4. Однако, когда я пытаюсь вызвать функцию addCount, она обычно обновляет значение count без необходимости выполнять горячую перезагрузку - это кажется для правильной работы
  5. Похоже, что вызов Future не обновляет должным образом содержимое моего списка значение

Моя актуальная проблема заключается в том, что при начальной загрузка, мой список значений не правильно инициализирует все свои значения, как задумано

Надеюсь, вы, ребята, можете помочь мне в этом. Спасибо.

ОБНОВЛЕНИЕ: Ниже показано, как я использую класс ChangeNotifier выше

class ParentProvider extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<MainProvider>(
          create: (context) => MainProvider(),
        ),
      ],
      child: ParentWidget(),
    );
  }
}

class ParentWidget extends StatelessWidget {
  final GlobalKey<AnimatedListState> listKey = GlobalKey<AnimatedListState>();

  @override
  Widget build(BuildContext context) {
    var mainProvider = Provider.of<MainProvider>(context);

    buildItem(BuildContext context, int index, Animation animation) {
      print('buildItem');

      var _object = mainProvider.list[index];
      var _widget;

      if (_object is Widget) {
        _widget = _object;
      } else if (_object is ModelItem) {
        _widget = Text(_object.unitNumber.toString());
      }

      return SizeTransition(
        key: ValueKey<int>(index),
        axis: Axis.vertical,
        sizeFactor: animation,
        child: InkWell(
          onTap: () {
            listKey.currentState.removeItem(index,
                (context, animation) => buildItem(context, index, animation),
                duration: const Duration(milliseconds: 300));
            mainProvider.list.removeAt(index);
            mainProvider.addCount();
          },
          child: Card(
            child: Padding(
              padding: const EdgeInsets.all(32.0),
              child: _widget,
            ),
          ),
        ),
      );
    }

    return Scaffold(
      appBar: AppBar(),
      body: Container(
        color: Colors.white,
        child: Padding(
          padding: const EdgeInsets.all(32.0),
          child: mainProvider.list == null
              ? Container()
              : AnimatedList(
                  key: listKey,
                  initialItemCount: mainProvider.list.length,
                  itemBuilder:
                      (BuildContext context, int index, Animation animation) =>
                          buildItem(context, index, animation),
                ),
        ),
      ),
    );
  }
}

1 Ответ

0 голосов
/ 28 февраля 2020

Вы запрашиваете у вашего провайдера StatelessWidget. Таким образом, ChangeNotifier не может инициировать восстановление вашего виджета, потому что нет состояния для восстановления. Вы должны либо конвертировать ParentWidget в StatefulWidget, либо вам нужно, чтобы ваш провайдер использовал Consumer вместо Provider.of:

class ParentWidget extends StatelessWidget {
  final GlobalKey<AnimatedListState> listKey = GlobalKey<AnimatedListState>();

  @override
  Widget build(BuildContext context) {
    return Consumer<MainProvider>(
      builder: (BuildContext context, MainProvider mainProvider, _) {
        ...
      }
    );
  }

В сторону, как вы Вы используете провайдера, чтобы добавить MainProvider к своему провайдеру и затем извлечь его из своего непосредственного потомка. Если это единственное место, где вы извлекаете MainProvider, это делает шаблон поставщика избыточным, так как вы можете просто объявить его в ParentWidget или даже просто получить список изображений, используя FutureBuilder. Использование провайдера - хороший шаг к правильному управлению состоянием, но также следует избегать чрезмерной разработки приложения.

...