0

I have following code where I am building a stateful child widget list in the outer page widget. I was expecting the initState() of the child widgets will be called only once but apparently the initState() is called every time I load the outer page.

Wondering why it is happening. Is my understanding of stateful widget, wrong?

class NotificationPage extends StatelessWidget {

 @override
 Widget build(BuildContext context) {
   return CustomScrollView(
        slivers: <Widget>[
          SliverOverlapInjector(
            handle:
                NestedScrollView.sliverOverlapAbsorberHandleFor(context),
          ),
          SliverFixedExtentList(
            itemExtent: 82.0,
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return Container(
                  alignment: Alignment.center,
                  child: NotificationListItem(
                    title: Provider.of<FCMService>(context).notificationList[index].title,
                    content: Provider.of<FCMService>(context).notificationList[index].body,
                  ), 
                );
              },
              childCount: Provider.of<FCMService>(context).notificationList.length,
            ),
          ),
        ],
      );
 }

}
 
class NotificationListItem extends StatefulWidget {
   final Widget image;
   final String title;
   final String content;

   NotificationListItem({
      this.image = const FlutterLogo(size: 48.0),
      this.title,
      this.content,
   });

   @override
   _NotificationListItemState createState() => _NotificationListItemState();
}

class _NotificationListItemState extends State<NotificationListItem> {
   bool _unseenMessage;

   @override
   void initState() {
    _unseenMessage = true;    // <==== This is setting everytime I go to NotificationPage
     print('--------------------- in the initState()');
     super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Card(
            elevation: 2.0,
            color: Colors.white,
            margin: EdgeInsets.all(10.0),
            child: ListTile(
            leading: this.widget.image,
            title: Text(this.widget.title,),
            subtitle: Text(this.widget.content,),
            horizontalTitleGap: 40.0,
            dense: false,
            onTap: () => {
                  if (_unseenMessage == true)
                  {
                      setState(() {
                       _unseenMessage = false;
                      }),
                      Provider.of<FCMService>(context, listen: false)
                     .decrementUnreadNotifications(),
                 }
              },
            ),
          );
      }
 }


  
Ishan Hettiarachchi
  • 1,426
  • 2
  • 19
  • 31
  • This may help https://stackoverflow.com/questions/54759920/flutter-why-is-child-widgets-initstate-is-not-called-on-every-rebuild-of-pa https://stackoverflow.com/questions/52295949/what-is-initstate-and-super-initstate-in-flutter – ghost deathrider Jun 07 '21 at 15:21
  • What do you mean by "load the outer page"? Do you just mean rebuilding `NotificationPage`, or are you leaving that page entirely and coming back later? – Nitrodon Jun 07 '21 at 15:29
  • @Nitrodon leaving the page and coming back using Navigation. – Ishan Hettiarachchi Jun 07 '21 at 15:29
  • @ghost I think that question is the inverse of what I ask. There the person who has asked the question expects the initState of the child to be run every time. I think it should be the other-way around. – Ishan Hettiarachchi Jun 07 '21 at 15:31
  • If initState() is a method which is called every time the widget is added to the widget tree, when you return such a widget in a Builder, it will be added and removed multiple times causing the initState to be called multiple times, I guess. ... If that's true it is not possible to retain the state using localState. – Ishan Hettiarachchi Jun 07 '21 at 15:40

0 Answers0