nondefinite
nondefinite

Reputation: 41

Flutter: Make a custom bottom bar sliding up when it appears

I am trying to design a music playlist page. So far I am able to create a listview with song cards. When I click on any song, a custom bottom bar appears and the audio starts playing. However, I just hold a state with boolean and show the bottom bar according to that. Instead, I want it to appear like sliding up and reach to the position. Let say in 0.5 seconds.

I have a custom NavBar class

class NavBar extends StatefulWidget

And I use this class in build similar to:

return Column(
  children: [
    SizedBox(
      height: constraints.maxHeight * 0.5,
      hild: SlidingBanners(),
    ),
    Expanded(
      child: Lists(),
    ),
    NavBar()
  ],
);

How can I such animation?

Upvotes: 2

Views: 1804

Answers (2)

Braden Bagby
Braden Bagby

Reputation: 293

Use a SizeTransition widget https://api.flutter.dev/flutter/widgets/SizeTransition-class.html

"SizeTransition acts as a ClipRect that animates either its width or its height, depending upon the value of axis. The alignment of the child along the axis is specified by the axisAlignment."

 Widget build(BuildContext context) {
 return SizeTransition(
  sizeFactor: CurvedAnimation(
    curve: Curves.fastOutSlowIn,
    parent: _animationController,
  ),
  child: Container(height: 100, color: Colors.blue)
);
}

init animation controller in stateful widgets initState()

  @override
void initState() {
super.initState();
_animationController = AnimationController(
    vsync: this, duration: const Duration(milliseconds: 500));
  }

Make sure your stateful widget uses SingleTickerProviderStateMixin

class _NavBarState extends State<NavBar>
with SingleTickerProviderStateMixin {
late AnimationController _animationController;

then open and close with

_animationController.forward()
_animationController.reverse()

You can pass the _animationController into the NavBar widget's constructor from its parent if you want the parent to control the animation.

Alternatively you can use an AnimatedContainer widget and setState with its height 0 or 100 depending on if Nav should be shown. This becomes a problem for some widgets that cannot be squished to height of 0 though and I would not recommend for any container that contains anything but text

Upvotes: 2

RukshanJS
RukshanJS

Reputation: 966

One solution would be to use a SnackBar widget. Since it's automatically animated, you wouldn't want to worry about manually animating the bottom bar. You can insert your Audio Player (bottom bar) widget to the child of the SizedBox.

The bottom bar is made visible by,

ScaffoldMessenger.of(context).showSnackBar(snackBar);

This bottom bar is dismissed (hidden) by dragging down or by,

ScaffoldMessenger.of(context).hideCurrentSnackBar();

There maybe many other solutions as well to this, but reading your question, I hope this is what you wanted.

return Center(
      child: ElevatedButton(
        onPressed: () {
          final snackBar = SnackBar(
            duration: Duration(days: 365),
            content: SizedBox(
              height: 100,
              //insert your audio player widget here
              child: Column(
                children: [
                  Text("YOUR AUDIOPLAYER WIDGET HERE"),
                  Text("Audio Controls Here"),
                  ElevatedButton(
                    onPressed: () {
                      ScaffoldMessenger.of(context).hideCurrentSnackBar();
                    },
                    child: Text("Audio Player Minimize"),
                  ),
                ],
              ),
            ),
          );
          ScaffoldMessenger.of(context).showSnackBar(snackBar);
        },
        child: Text('Open Audio Player'),
      ),
    );

Upvotes: 1

Related Questions