Widget not redrawing on Provider variable change – Flutter

Issue

I have a provider called "FavoritesProvider" which has a variable called "_favoritos" where I store a list of id’s.

What I am trying to do, is redraw a ListView widget every time a new item is added or removed to the favorites variable. Here is the function where I do that, where I update the variable and 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;}

The item I am trying to redraw is nested like this:

  • MainPage: Scaffold body containing an IndexedStack
  List<Widget> _widgetOptions = [
    HomePage(),
    FavoriteScreen(),
    CompletedScreen()
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: IndexedStack(
          index: _selectedIndex,
          children: _widgetOptions,
        ),
  • FavoriteScreen: Statless widget only containing FavDoneList widget of my own.
  • FavDoneList: Statefull widget that contains the list. -> I want to re-render it.
    I tried using a listener, but it does not redraw:
  @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,
    ));
  }

Can you help me understand what I am doing wrong? I can’t figure out how to redraw it.
Thanks!

Solution

I solved it by using something "ugly":

Since none of my Providers, Consumers or listeners would work, I aimed to reload the whole FavDoneList widget every time the middle bottom tab was pressed. It was a very small price to pay in terms of performance, and it won’t affect the user that much.

I did so like this on the Main Page:

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

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

Very important to pass the unique key, otherwise it does not work.

Answered By – MIPB

Answer Checked By – Willingham (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *