CustomScrollWidget, SliverList, SliverChildBuilderDelegate constantly rebuilds and degrades performance. Flutter

486

One of the things to consider when using nested structures is to avoid infinite loops. If a field is redrawn when a "state" changes, it will repeat itself in other loops under it. Please delete the specified area and try.

The code to be deleted:

// This field triggers repetition.

WidgetsBinding.instance.addPostFrameCallback((_) => setState(() {
    changeColor = constraints.biggest.height;
}));
Share:
486
whiteWolfie
Author by

whiteWolfie

Updated on November 25, 2022

Comments

  • whiteWolfie
    whiteWolfie over 1 year

    I was thinking of implementing SliverAppBar and a Scrollable items under it, so I have this code right now:

    CustomScrollView(
            semanticChildCount: categoryItems.length,
            physics: BouncingScrollPhysics(),
            slivers: [
              SliverAppBar(
                automaticallyImplyLeading: false,
                backgroundColor: Colors.white,
                elevation: 0,
                actions: [
                  Padding(
                    padding: EdgeInsets.only(right: 15),
                    child: IconButton(
                      onPressed: () {},
                      icon: Icon(
                        Icons.more_horiz,
                        color: changeColor == 80 ? Color(0xFFB2A588) : Colors.white,
                        size: 30,
                      ),
                    ),
                  )
                ],
                expandedHeight: MediaQuery.of(context).size.height / 3,
                stretch: true,
                pinned: true,
                flexibleSpace: LayoutBuilder(
                    builder: (BuildContext context, BoxConstraints constraints) {
                  // setting state for top to change color of more horiz
                  WidgetsBinding.instance.addPostFrameCallback((_) => setState(() {
                        changeColor = constraints.biggest.height;
                      }));
                  return FlexibleSpaceBar(
                    title: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          constraints.biggest.height == 80 ? 'Title' : '',
                          style: TextStyle(
                            fontSize: 25,
                            fontWeight: FontWeight.bold,
                            color: Color(0xFFB2A588),
                          ),
                        ),
                        Visibility(
                          visible: constraints.biggest.height == 80,
                          child: Icon(
                            Icons.keyboard_arrow_down,
                            size: 35,
                            color: Color(0xFFB2A588),
                          ),
                        )
                      ],
                    ),
                    stretchModes: [
                      StretchMode.zoomBackground,
                    ],
                    background: Stack(
                      children: [
                        // category image
                        Image.network(
                          'networkimage',
                          fit: BoxFit.cover,
                          width: double.infinity,
                        ),
                        // category title
                        Positioned(
                          bottom: 30,
                          left: 30,
                          child: Row(
                            children: [
                              SizedBox(
                                width: MediaQuery.of(context).size.width / 2.5,
                                child: Text(
                                  'Title',
                                  style: TextStyle(
                                      fontSize: 60,
                                      fontWeight: FontWeight.bold,
                                      color: Colors.white),
                                ),
                              ),
                            ],
                          ),
                        ),
                        // button
                        Positioned(
                          bottom: 30,
                          right: 30,
                          child: SizedBox(
                            width: MediaQuery.of(context).size.width / 4,
                            child: RaisedButton(
                              onPressed: () {
                                Navigator.pop(context);
                              },
                              color: Colors.white,
                              elevation: 4.0,
                              child: Text('View more',
                                  style: TextStyle(
                                      fontSize: 20,
                                      fontWeight: FontWeight.w600,
                                      color: Colors.black)),
                              shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(25.0)),
                            ),
                          ),
                        ),
                      ],
                    ),
                  );
                }),
              ),
              SliverList(
                delegate: SliverChildBuilderDelegate(
                  (BuildContext context, int index) {
                    print(index); },
              childCount: categoryItems.length,
            ),
          )
        ],
      )
    

    The print(index) statement gets executed every second constantly. Any ideas why is that happening? Working with SliverList for the first time.

    P.S. if you put some ListTiles for example inside the SliverChildBuilderDelegate it still executes print statement constantly.

  • whiteWolfie
    whiteWolfie over 3 years
    Thanks a lot, it did help with the constant rebuilding. Do you mind me asking one question? I wrote this set state function to change the color of the IconButton in actions of SliverAppBar because I wanted it to be white when SliverAppBar is expanded and brown when it is collapsed. How can I achieve it now, without calling the set state that triggers repetition?