0

Stackoverflowers!

I'm using an BottomAppBar inside the bottomNavigationBar section of the Scaffold. The problem is that it doesn't persists while I'm navigating. I used the persistent_bottom_nav_bar plugin, but it doesn't work with my custom navigation bar because it has a ripple animation in one button and a bottomSheet that is over the keyboard.

home_page.dart

This file has the CustomNavigationBar and the main pages for each item on it.

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
  NavigationProvider? navigationProvider;
  AnimationController? rippleController;
  AnimationController? scaleController;
  Animation<double>? rippleAnimation;
  Animation<double>? scaleAnimation;

  @override
  void initState() {
    super.initState();
    rippleController = AnimationController(
        vsync: this, duration: const Duration(milliseconds: 500));
    scaleController = AnimationController(
        vsync: this, duration: const Duration(milliseconds: 500))
      ..addStatusListener((status) {
        if (status == AnimationStatus.completed) {
          scaleController!.reverse();
          Navigator.push(
              context,
              PageTransition(
                type: PageTransitionType.bottomToTop,
                child: pages.elementAt(2),
                childCurrent: widget,
                fullscreenDialog: true,
              )).whenComplete(() => setState(() {
                buttonColor = Colors.black;
              }));
        }
      });
    rippleAnimation =
        Tween<double>(begin: 80.0, end: 90.0).animate(rippleController!)
          ..addStatusListener((status) {
            if (status == AnimationStatus.completed) {
              rippleController!.reverse();
            } else if (status == AnimationStatus.dismissed) {
              rippleController!.forward();
            }
          });
    scaleAnimation =
        Tween<double>(begin: 1.0, end: 30.0).animate(scaleController!);

    rippleController!.forward();
  }

  @override
  void dispose() {
    rippleController!.dispose();
    scaleController!.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    navigationProvider = Provider.of<NavigationProvider>(context);
    return Scaffold(
      body:
          pages.elementAt(navigationProvider!.bottomNavigationBarSelectedIndex),
      bottomNavigationBar: CustomNavigationBar(
          rippleController: rippleController,
          scaleController: scaleController,
          rippleAnimation: rippleAnimation,
          scaleAnimation: scaleAnimation),
    );
  }
}

custom_navigation_bar.dart

This file contains the properties of the CustomNavigationBar.

class CustomNavigationBar extends StatefulWidget {
  const CustomNavigationBar({
    super.key,
    this.rippleController,
    this.scaleController,
    this.rippleAnimation,
    this.scaleAnimation,
  });

  final AnimationController? rippleController;
  final AnimationController? scaleController;

  final Animation<double>? rippleAnimation;
  final Animation<double>? scaleAnimation;

  @override
  State<CustomNavigationBar> createState() => _CustomNavigationBarState();
}

class _CustomNavigationBarState extends State<CustomNavigationBar> {
  @override
  Widget build(BuildContext context) {
    final navigationProvider = Provider.of<NavigationProvider>(context);

    return BottomAppBar(
      child: IconTheme(
        data: const IconThemeData(color: Colors.black, size: 36),
        child: Padding(
          padding: const EdgeInsets.fromLTRB(10, 5, 10, 5),
          child: Row(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Wrap(
                crossAxisAlignment: WrapCrossAlignment.center,
                direction: Axis.vertical,
                children: [
                  IconButton(
                    icon: ...,
                    padding: ...,
                    constraints: ...,
                    onPressed: () {
                      //Here I change the selected index with Provider.
                      ...
                    },
                  ),
                  Text(
                    title,
                    style: ...,
                  ),
                ],
              ),
              const Spacer(),
              Wrap(...),
              const Spacer(),
              InkWell(
                onTap: () {
                  setState(
                    () {
                      //Executes the ripple animation.
                      widget.scaleController!.forward();
                    },
                  );
                },
                child: AnimatedBuilder(
                  animation: widget.scaleAnimation!,
                  builder: (context, child) => Transform.scale(
                    scale: widget.scaleAnimation!.value,
                    child: Container(
                      width: 50,
                      height: 50,
                      margin: const EdgeInsets.all(10),
                      decoration: const BoxDecoration(
                          shape: BoxShape.circle, color: Colors.blue),
                      child: Icon(Icons.add,
                          color: widget.scaleAnimation!.value == 1.0
                              ? Colors.white
                              : Colors.blue),
                    ),
                  ),
                ),
              ),
              const Spacer(),
              Wrap(...),
              const Spacer(),
              Wrap(...),
            ],
          ),
        ),
      ),
    );
  }
}

As you can see, I use Provider to manage the state of the CustomNavigationBar when it changes the index.

Example of what I want:

This app is Splitwise and it has some pages with the navigation bar and others without it. That ripple animation is similar to mine. Also the bottom sheet has the same effect in my app.

Example

I'll wait for all your suggestions, thanks!

0 Answers0