title: How to refresh a widget based on another widget's on tap method
body: <p>In my Flutter UI, I want to refresh the item list whenever a user chooses a particular category. I also want to make the chosen category become the active category. Here's how my UI looks like:</p>
  <p><a href="https://i.stack.imgur.com/JzlAk.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/JzlAk.png" alt="enter image description here" /></a></p>
  <p>Here's my code which displays the categories:</p>
  <pre><code>@override
    Widget build(BuildContext context) {
       var categoriesData =   Provider.of&lt;Categories&gt;(context);
      return SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: categoriesData.items
            .map(
              (catData) =&gt; CategoryItemNew(
                    id:catData.id,
                    title:catData.title,
                    isActive:categoriesData.items.indexOf(catData)==0?true:false
                  ),
            )
            .toList(),
        ),
      );
    }
  </code></pre>
  <p>Here's the code for each category item:</p>
  <pre><code>class CategoryItemNew extends StatefulWidget {
    final String title;
    final String id;
    bool isActive;
    final Function press;
    CategoryItemNew({
      @required this.id,
      @required this.title,
      this.isActive
    });
  
    @override
    _CategoryItemNewState createState() =&gt; _CategoryItemNewState();
  }
  
  class _CategoryItemNewState extends State&lt;CategoryItemNew&gt; {
    @override
    Widget build(BuildContext context) {
      return GestureDetector(
        onTap: () =&gt; selectCategory(context),
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15),
          child: Column(
            children: &lt;Widget&gt;[
              Text(
                widget.title,
                style: widget.isActive
                    ? TextStyle(
                        color: kTextColor,
                        fontWeight: FontWeight.bold,
                      )
                    : TextStyle(fontSize: 12),
              ),
              if (widget.isActive)
                Container(
                  margin: EdgeInsets.symmetric(vertical: 5),
                  height: 3,
                  width: 22,
                  decoration: BoxDecoration(
                    color: kPrimaryColor,
                    borderRadius: BorderRadius.circular(10),
                  ),
                ),
            ],
          ),
        ),
      );
    }
  
    void selectCategory(BuildContext ctx) {
     // What should I do here? 
    }
  }
  </code></pre>
  <p>And Here's the code to display the products:</p>
  <pre><code>class ItemList extends StatefulWidget {
    static const routeName = '/item-list';
    String title = ''; 
    ItemList(this.title);  
  
    @override
    _ItemListState createState() =&gt; _ItemListState();
  }
  
  class _ItemListState extends State&lt;ItemList&gt; {
    var _isInit = true;
    var _isLoading = false;
   
  
     void didChangeDependencies() {
      if (_isInit) {
        setState(() {
          _isLoading = true;
        });
         Provider.of&lt;Products&gt;(context).fetchAndSetProducts(widget.title, true).then((_) {
          setState(() {
            _isLoading = false;
          });
        });
      }
      _isInit = false;
      super.didChangeDependencies();
    }
  
    @override
    Widget build(BuildContext context) {
       final productsData =   Provider.of&lt;Products&gt;(context); 
      return _isLoading? CircularProgressIndicator():SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: Row(
           children:productsData.items
            .map(
              (productData) =&gt; ItemCard(
                    svgSrc: &quot;assets/icons/burger_beer.svg&quot;,
                    //id:catData.id,
                    title: productData.title
                    //title:productData.title,
                  ),
            )
            .toList(),
        ),
      );
    }
  }
  </code></pre>
  <p>When the app starts, I am able to fetch the categories and am also able to show the items for the &quot;BURGERS &amp; WRAPS&quot; category. However, I don't know how to refresh the item list when user chooses another category and also how to make that category be the active category.</p>
  <p><strong>Updated CategoryItem class after Mickael's reponse</strong></p>
  <pre><code> String previousId =''; 
  // ignore: must_be_immutable
  class CategoryItemNew extends StatefulWidget {
    final String title;
    final String id;
    bool isActive;
    final Function press;
    CategoryItemNew({
      @required this.id,
      @required this.title,
      this.isActive,
    });
    @override
    _CategoryItemNewState createState() =&gt; _CategoryItemNewState();
  
  }
  
  class _CategoryItemNewState extends State&lt;CategoryItemNew&gt; {
  
    String id; 
    ValueNotifier valueNotifier;
     
    void initState() {
      id = widget.id;
     valueNotifier = ValueNotifier(previousId);
     print('ID in initstate is ' + id); 
      super.initState();
    }
  
    isIdUpdated(String id) {
       print('previous in updateid is ' + previousId);
      if(previousId != id)
      { 
        previousId = id; 
       valueNotifier.value = id;
       print('ID in updateid is ' + id); 
      }
    }
    @override
    Widget build(BuildContext context) {
      return GestureDetector(
        onTap: () =&gt; selectCategory(context),
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15),
          child: Column(
            children: &lt;Widget&gt;[
              Text(
                widget.title,
                style: widget.isActive
                    ? TextStyle(
                        color: kTextColor,
                        fontWeight: FontWeight.bold,
                      )
                    : TextStyle(fontSize: 12),
              ),
              if (widget.isActive)
                Container(
                  margin: EdgeInsets.symmetric(vertical: 5),
                  height: 3,
                  width: 22,
                  decoration: BoxDecoration(
                    color: kPrimaryColor,
                    borderRadius: BorderRadius.circular(10),
                  ),
                ),
            ],
          ),
        ),
      );
    }
  
    ValueListenableBuilder selectCategory(BuildContext ctx) {
       isIdUpdated(id); 
     return ValueListenableBuilder(
        valueListenable: valueNotifier,
        builder: (context, value, child) {
          print('inside listenabele builder'); 
          return ItemList(widget.title);
        },
      );
    }
  
     
  }
  </code></pre>
  <p>Notice that I have a print statement inside the builder of ValueListenableBuilder. This print statement never gets executed. What am I doing wrong?</p>