簡體   English   中英

如何在 Flutter Provider 中正確初始化 Future

[英]How to properly initialize a Future in Flutter Provider

所以我試圖通過 Future Call 在我的提供商中建立一個列表。

到目前為止,我有以下 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();
  }
}

但是,每當我使用列表值時都會發生這種情況:

  1. 我可以確認我的 initList 函數正在正確執行
  2. 可用列表值的初始內容是我首先通過addToList函數插入的Text()小部件,這意味着此時列表中似乎只有一項
  3. 當我執行熱重載時,列表的其余內容現在似乎出現了

筆記:

  1. 我在 AnimatedList 小部件中使用list的值,所以我應該顯示list的內容
  2. 最初出現的是我的列表值的內容只有一項
  3. 在執行 Future 調用期間,我的列表值似乎不會自動更新
  4. 但是,當我嘗試調用 addCount 函數時,它通常會更新count的值,而無需執行 Hot Reload - 這似乎運行正常
  5. 看來 Future 調用沒有正確更新我的列表值的內容

我真正關心的是,在初始加載時,我的列表值沒有按預期正確初始化所有值

希望大家能幫我解決這個問題。 謝謝你。

更新:下面顯示了我如何使用上面的 ChangeNotifierClass

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),
                ),
        ),
      ),
    );
  }
}

您正在從StatelessWidget檢索您的提供者。 因此, ChangeNotifier無法觸發您的小部件重建,因為沒有要重建的狀態。 您必須將ParentWidget轉換為StatefulWidget或者您需要使用Consumer而不是Provider.of來獲取您的提供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, _) {
        ...
      }
    );
  }

順便說一句,您使用 provider 的方式是將MainProvider添加到其提供者,然后從其直接子項中檢索它。 如果這是您檢索MainProvider的唯一位置,則這會使提供者模式變得多余,因為您可以輕松地在ParentWidget聲明它,或者甚至只是使用FutureBuilder獲取圖像列表。 使用 provider 是實現正確狀態管理的良好步驟,但也要小心過度設計您的應用程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM