【问题标题】:Widget not redrawing on Provider variable change - Flutter小部件未在提供程序变量更改时重绘 - Flutter
【发布时间】:2021-10-12 14:03:12
【问题描述】:

我有一个名为“FavoritesProvider”的提供程序,它有一个名为“_favoritos”的变量,我在其中存储了一个 id 列表。

我想要做的是,每次在收藏夹变量中添加或删除新项目时重绘一个 ListView 小部件。这是我执行此操作的函数,我在其中更新变量和 notifyListeners。

    Future setFavorites(
    int id,
  ) async {
    final prefs = await SharedPreferences.getInstance();
    String _receivedData = (prefs.getString('favorites') ?? "");
    List _decodedData = [];
    if (_receivedData != "") {
      _decodedData = json.decode(_receivedData);
    }
    String _sentData = "";

    if (_decodedData.contains(id)) {
      _decodedData.remove(id);
      _sentData = json.encode(_decodedData);
    } else {
      _decodedData.add(id);
      _sentData = json.encode(_decodedData);
    }

    prefs.setString("favorites", _sentData);
    _favoritos = _decodedData;
    notifyListeners();
    return _favoritos;}

我试图重绘的项目是这样嵌套的:

  • MainPage:包含 IndexedStack 的脚手架主体
  List<Widget> _widgetOptions = [
    HomePage(),
    FavoriteScreen(),
    CompletedScreen()
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: IndexedStack(
          index: _selectedIndex,
          children: _widgetOptions,
        ),
  • FavoriteScreen:无状态小部件,仅包含我自己的 FavDoneList 小部件。
  • FavDoneList:包含列表的全状态小部件。 -> 我想重新渲染它。 我尝试使用监听器,但它没有重绘:
  @override
  Widget build(BuildContext context) {
    var _favorites = Provider.of<FavoritesProvider>(context).favoritos;

    if (flag == true) {
      if (_favorites.isEmpty) {
        return Center(child: Text("No has añadido favoritos"));
      }

      return ListView(
        children: _loadFavorites(_favorites),
      );
    }
    return Center(
        child: CircularProgressIndicator(
      color: Colors.red,
    ));
  }

你能帮我理解我做错了什么吗?我不知道如何重绘它。 谢谢!

【问题讨论】:

  • 请添加错误消息或一些指示问题所在。谢谢!
  • 没有错误消息@David 它只是没有按照您对提供者的期望更新小部件,但尽管如此,它仍然可以正常工作!
  • 我在您的小部件树中的任何地方都看不到提供者小部件。您是否使用了正确的版本(可能是 ChangeNotifierProvider)?如果是这样,您可以添加更多的小部件树来包含它吗?
  • 另外,您没有显示调用 setFavorites 的方式/位置,这也可能有用。您确定基础数据实际上正在发生变化吗?尝试添加断点并检查 _decodedData 是否确实包含新信息
  • @David 是的,对不起。 ChangeNotifierProvider 位于我的应用程序的根目录,因此它应该将信息传递给我的应用程序内的所有组件。 setFavorites 在另一个小部件中的一个按钮中被调用。但它会起作用,因为一旦我重新加载应用程序,页面就会更新。 :/ 我今天会尝试更新我的问题,很抱歉造成混乱。

标签: flutter dart flutter-provider flutter-change-notifier


【解决方案1】:

我通过使用“丑陋”的东西来解决它:

由于我的 Providers、Consumers 或 listeners 都不起作用,所以我的目标是在每次按下中间底部选项卡时重新加载整个 FavDoneList 小部件。就性能而言,这是一个很小的代价,并且不会对用户产生太大影响。

我在主页上这样做了:

  void _onItemTapped(int index) {
if (index == 1) {
  setState(() {
    _widgetOptions.removeAt(1);
    _widgetOptions.insert(1, FavDoneList(key: UniqueKey()));

    _selectedIndex = index;
  });
} else {
  setState(() {
    _selectedIndex = index;
  });
}}

传递唯一密钥很重要,否则不起作用。

【讨论】:

    猜你喜欢
    • 2021-08-17
    • 2020-07-15
    • 2020-10-07
    • 1970-01-01
    • 1970-01-01
    • 2021-07-18
    • 2020-08-24
    • 2021-11-22
    • 2021-06-24
    相关资源
    最近更新 更多