title: Flutter Setstate inside Listview.builder's builditem function not reloading
body: <p>I have a streambuilder that loads information from firestore. Then I use a listview.builder to display the information. The displayed information is being called by the function firstBuildItem or buildItem. </p>
  
  <p>The functionality that I want is that when the user clicks on the container that is wrapped with a gesturedetector, I want another widget to be expanded below the main widget. I'm not sure how to achieve this with flutter because since each message is an item insider listview.builder, the boolean value needs to be local inside the function since every function has its own boolean that is checking for if the list item was clicked. I would like to find out how to fix my code so that each item responds when clicked inside the listview by expanding.</p>
  
  <pre><code>ListView.builder(
  padding: EdgeInsets.all(10.0),
  itemBuilder: (context, index) =&gt;
  index == 0 ? firstBuildItem(index, snapshot.data.documents[index]) : buildItem(index, snapshot.data.documents[index], snapshot.data.documents[index-1]),
  itemCount: snapshot.data.documents.length,
  reverse: true,
  controller: listScrollController,
  ),
  </code></pre>
  
  <p>then here is the builditem function:</p>
  
  <pre><code>Widget firstBuildItem(int index, DocumentSnapshot mainDocument) {
  
    ///If the box is expanded
    bool _isExpanded = false;
  
    ///Toggle the box to expand or collapse
    void _toggleExpand() {
      setState(() {
        _isExpanded = !_isExpanded;
      });
    }
  
  
    return GestureDetector(
  
      onTap: _toggleExpand,
  
      child: Container(
  
        color: _isExpanded ? Colors.blueGrey : null,
  
        child: Column(
  
  
          children: &lt;Widget&gt;[
  
            Column(
              children: &lt;Widget&gt;[
  
                SizedBox(height: 20.0),
  
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: &lt;Widget&gt;[
  
                    ChatDateHeader(timestamp: mainDocument['timestamp']),
  
                  ],
                ),
              ],
            ),
  
            Column(
  
              children: &lt;Widget&gt;[
  
                Row(
                  children: &lt;Widget&gt;[
                    Container(
                      child: Text(
                        mainDocument['content'],
                        style: TextStyle(color: primaryColor),
                      ),
                      padding: EdgeInsets.fromLTRB(15.0, 10.0, 15.0, 10.0),
  
                    ),
                  ],
                  mainAxisAlignment: MainAxisAlignment.end,
                ),
  
                getTime(mainDocument['timestamp'], true),
  
                ExpandedSection(
                  expand: _isExpanded,
                  child: getDate(mainDocument['timestamp'], true),
                ),
  
                SizedBox(height: 20.0),
  
              ],
              crossAxisAlignment: CrossAxisAlignment.end,
            ),
          ],
        ),
      ),
    );
  }
  </code></pre>
  
  <p>and then the expanded widget:</p>
  
  <pre><code>class ExpandedSection extends StatefulWidget {
  
    final Widget child;
    final bool expand;
    ExpandedSection({this.expand = false, this.child});
  
    @override
    _ExpandedSectionState createState() =&gt; _ExpandedSectionState();
  }
  
  class _ExpandedSectionState extends State&lt;ExpandedSection&gt; with SingleTickerProviderStateMixin {
    AnimationController expandController;
    Animation&lt;double&gt; animation;
  
    @override
    void initState() {
      super.initState();
      prepareAnimations();
    }
  
    ///Setting up the animation
    void prepareAnimations() {
      expandController = AnimationController(
          vsync: this,
          duration: Duration(milliseconds: 500)
      );
      Animation curve = CurvedAnimation(
        parent: expandController,
        curve: Curves.fastOutSlowIn,
      );
      animation = Tween(begin: 0.0, end: 1.0).animate(curve)
        ..addListener(() {
          setState(() {
  
          });
        }
        );
    }
  
    @override
    void didUpdateWidget(ExpandedSection oldWidget) {
      super.didUpdateWidget(oldWidget);
      if(widget.expand) {
        expandController.forward();
      }
      else {
        expandController.reverse();
      }
    }
  
    @override
    void dispose() {
      expandController.dispose();
      super.dispose();
    }
  
    @override
    Widget build(BuildContext context) {
      return SizeTransition(
          axisAlignment: 1.0,
          sizeFactor: animation,
          child: widget.child
      );
    }
  }
  </code></pre>