1

Good morning friends, I'm trying to make the appbar transparent or white in scrollable parts. For me, this solution An efficient way in Flutter to change appbar color when scrolled works, but as the person said, I don't want to use setState continuously and do it in every separate component, so I'm trying to do what is mentioned in the comment. For this reason, I created a common appbar widget so that I can use it in other components. I made the CustomAppBar widget statefull, but I don't know where to add the scrollController. Therefore, I see errors. If anyone has time, can you help? The code below is the widget where I call CustomAppBar.

  import ...
    
      const ExtractionBody({Key? key, required this.goal}) : super(key: key);
      final Objective goal;
    
      @override
      ExtractionBodyState createState() => ExtractionBodyState();
    }
    
    class ExtractionBodyState extends ConsumerState<ExtractionBody> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          extendBodyBehindAppBar: true,
          appBar: PreferredSize(
            preferredSize: const Size.fromHeight(100),
            child: CustomAppBar(
              icon: IconButton(
                icon: const Icon(PhosphorIcons.xBold),
                onPressed: () => Navigator.of(context).pushNamedAndRemoveUntil(
                  HomePage.routeName,
                  (route) => false,
                ),
              ),
            ),
          ),
          body: ExtractionRequestContent(
              goal: widget.goal, scrollController: _scrollController),
        );
      }
    }

Finally, this is my CustomAppBar code. Thank you very much in advance. and have a good weekend everyone

class CustomAppBar extends StatefulHookConsumerWidget {
  static String routeName = "/extraction_body";

  const CustomAppBar({Key? key, this.icon})
      : preferredSize = const Size.fromWidth(50),
        super(key: key);
  final Widget? icon;
  @override
  final Size preferredSize; // default is 56.0
  @override
  CustomAppBarState createState() => CustomAppBarState();

}

class CustomAppBarState extends ConsumerState<CustomAppBar> {
  bool isAppbarCollapsing = false;
  final ScrollController _scrollController = ScrollController();

  @override
  void initState() {
    super.initState();
    _initializeController();
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

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

  @override
  Widget build(BuildContext context) {
    return AppBar(
      elevation: 0,
      backgroundColor:
          isAppbarCollapsing ? AppColors.monochromeWhite : Colors.transparent,
      title: Text(context.l10n.buttonCancel),
      titleSpacing: 4,
      leading: widget.icon,
    );
  }
}

Thanks!

1 Answers1

1

Instead of define ScrollController in CustomAppBar, pass it in constructor like this:

 class CustomAppBar extends StatefulHookConsumerWidget {
  static String routeName = "/extraction_body";

  const CustomAppBar({Key? key, this.icon, required this.scrollController})
      : preferredSize = const Size.fromWidth(50),
        super(key: key);
  final Widget? icon;
  final ScrollController scrollController;
  @override
  final Size preferredSize; // default is 56.0
  @override
  CustomAppBarState createState() => CustomAppBarState();

}

and use it like this:

class MyApp extends StatelessWidget {
  MyApp({Key? key}) : super(key: key);
  final ScrollController scrollController = ScrollController(); //<---- define scrollController here
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: Scaffold(
          appBar: PreferredSize(
              preferredSize: const Size.fromHeight(100),
              child: CustomAppbar(scrollController: scrollController)),
          body: ListView.builder(
            controller: scrollController,
            itemCount: 10,
            itemBuilder: (BuildContext context, int index) {
              return Container(
                height: 100,
                width: 100,
                color: Colors.red,
                margin: EdgeInsets.all(12),
              );
            },
          ),
        ));
  }
}

enter image description here

eamirho3ein
  • 16,619
  • 2
  • 12
  • 23
  • Hello thanks for the answer Can I ask something? How did you get this scrollController: scrollController part in the another widget? I wrote what you say but here is giving error. :/ preferredSize: const Size.fromHeight(100), child: CustomAppbar(scrollController: scrollController)), body: ListView.builder( controller: scrollController, Thanks! –  Sep 03 '22 at 08:39
  • If you issue is that its not recognize scrollController? I update my answer. check it out – eamirho3ein Sep 03 '22 at 08:43
  • Glad to hear that, if it helps you, please approve and up vote it, so other people could find it. – eamirho3ein Sep 03 '22 at 09:25