2

I have a CustomAppBar and a PageViewer. I would like to animate a ProgressBar inside the CustomAppBar, if the user is changing the Page.

This is my Top-Level-Page looks like this:

class EntryPage extends StatelessWidget {
  
  final List<Widget> _pages = [BasicValuesPage(), GeneralConditionPage()];
  int currentStep = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: PreferredSize(
        preferredSize: Size.fromHeight(
          scaleWidth(120),
        ),
        child: Container(
          decoration: BoxDecoration(
              color: AppColors.secondary,
              borderRadius: new BorderRadius.only(
                bottomLeft: Radius.circular(
                  scaleWidth(20),
                ),
                bottomRight: Radius.circular(
                  scaleWidth(20),
                ),
              )),
          child: AppBarContent(
            step: currentStep,
          ),
        ),
      ),
      body: Center(
        child: _buildPageViewer(),
      ),
    );
  }

  PageView _buildPageViewer() {
    return PageView.builder(
      itemBuilder: (context, position) {
        return _pages[position];
      },
      itemCount: _pages.length,
      onPageChanged: (int step) {
        currentStep = step;
      },
    );
  }
}

As you can see I am using AppBarContent where I am passing currentStep which I updated at the bottom inside my _buildPageView, onPageChanged.

This is my AppBarContent:

class AppBarContent extends StatelessWidget {
  final int step;

  const AppBarContent({required this.step, Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
         ProgressBar(
           step: step,
         ),
      ],
     );
    }
 }

And I as you can see I am also passing step to my ProgressBar, which is where I actually want to animate the ContainerWidth:

class ProgressBar extends StatelessWidget {
  final int step;

  const ProgressBar({required this.step, Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final double _containerWidth = MediaQuery.of(context).size.width - (2 * 16);
    return Stack(
      children: [
        Container(
          color: AppColors.white.withAlpha(37),
          height: scaleWidth(6),
          width: _containerWidth,
        ),
        AnimatedContainer(
          width: _containerWidth * (step * 7),
          duration: Duration(milliseconds: 100),
        ),
      ],
    );
  }
}

My goal is that if the user changes the page, the width of the AnimatedContainer in my ProgressBar should be animated to the new width.

How can I achieve that? I searched for it but couldn't find anything. Any help is appreciated! Let me know if you need any more info!

Chris
  • 1,828
  • 6
  • 40
  • 108

1 Answers1

0

Wrap this callback function

      onPageChanged: (int step) {
        currentStep = step;
      },

in setState:

      onPageChanged: (int step) {
        setState(){
          currentStep = step;
        }
      },

If you are using Dart version 2.1 integer literals may be directly used where double is expected, if older version you will have to additionally translate your int step to double.

Simon Sot
  • 2,748
  • 2
  • 10
  • 23