I have been working on the Scroll of the page, and at the same time, doing these things:

  • Changing color of the AppBar background when scrolling
  • Changing the AppBar background to transparent when scrolled to the top

My code works fine, but the problem here is, it is laggy when it comes to smooth scrolling.

I have read about the flutter documentation, and found out, that, using setState() inside the addListener() is not the best practice you can follow.

I have tried searching more about it, but couldn't find an efficient solution.

Here is my code:

class HomePageState extends State<HomePage> {
  int _selectIndex = 0;
  bool isAppbarCollapsing = false;
  final ScrollController _homeController = new ScrollController();

  void initState() {

    // for adding appbar background color change effect 
    // when scrolled

  void dispose(){

  void _initializeController(){
    _homeController.addListener(() {
      if(_homeController.offset == 0.0 && !_homeController.position.outOfRange){
        //Fully expanded situation
        if(!mounted) return;
        setState(() => isAppbarCollapsing = false);
      if(_homeController.offset >= 9.0 && !_homeController.position.outOfRange){
        //Collapsing situation
        if(!mounted) return;
        setState(()  => isAppbarCollapsing = true);

  Widget build(BuildContext context) {
     return Scaffold(
       appBar: AppBar(
          // here is how I am changing the color
          backgroundColor: isAppbarCollapsing ? Colors.white.withOpacity(0.8) : Colors.transparent
       body: Container(
         height: MediaQuery.of(context).size.height,
         width: MediaQuery.of(context).size.width,
         child: ListView(
           controller: _homeController

Solution 1: Jagraj Singh

You can try making a new stateful widget which returns an appbar. Pass the scroll controller to that widget and apply listeners in that appbar widget and then perform setState in the appbar widget.

What this will do is instead of rebuilding the whole screen it'll just rebuild the appbar only.