Search code examples
flutterflutter-animation

Flutter - PageController " ScrollController not attached to any scroll views."


Is there a way to animate to a page using PageController after awaiting an async function without causing the exception below to be thrown?

Exception:

_AssertionError ('package:flutter/src/widgets/scroll_controller.dart': Failed assertion: line 107 pos 12: '_positions.isNotEmpty': ScrollController not attached to any scroll views.)

Example widget:


class ExampleWidget extends StatelessWidget {
  ExampleWidget({super.key});

  final pageController = PageController();
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        PageView(
          controller: pageController,
          physics: const NeverScrollableScrollPhysics(),
          children: [],
        ),
        InkWell(
          onTap: () async {
            await exampleFn();
            await Future.delayed(const Duration()); // to wait for UI to build
            pageController.animateToPage(
              1,
              duration: const Duration(milliseconds: 500),
              curve: Curves.easeInOut
            );
          },
        )
      ],
    );
  }
}

Awaiting with if (pageController.hasClients) causes the animation to not occur. What is the right way to do this?


Solution

  • I think it's working fine, you have to add the children property in the PageView, You can checkout this example:

    import 'package:flutter/material.dart';
    
    class ExampleWidget extends StatelessWidget {
      ExampleWidget({super.key});
    
      final pageController = PageController();
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Stack(
            children: [
              PageView(
                controller: pageController,
                physics: const NeverScrollableScrollPhysics(),
                children: [
                  Container(
                    color: Colors.amber,
                  ),
                  Container(
                    color: Colors.red,
                  )
                ],
              ),
              InkWell(
                onTap: () async {
                  // await exampleFn();
                  await Future.delayed(
                      const Duration(seconds: 2)); // to wait for UI to build
                  pageController.animateToPage(1,
                      duration: const Duration(milliseconds: 500),
                      curve: Curves.easeInOut);
                },
              )
            ],
          ),
        );
      }
    }
    

    Here I have delayed for 2 seconds and it works perfectly fine.