skip to Main Content

I am building a flutter application and now I am working on the on boarding page. I am using Getx for state management and logic. In the on boarding screen I have a PageView.builder which returns the pages of the on boarding page with a horizontal scrolling axis. I also used smooth page indicator. My page controller is in the OnBoardingController which extends GetxController. When I scroll and move to other pages the page indicator is not being updated.

My next button is also not working it gives an error that says: ScrollController attached to multiple scroll views.

Here is where I used the pageController from GetxController code:

class OnBoardingPage extends StatelessWidget {
  const OnBoardingPage({super.key});

  @override
  Widget build(BuildContext context) {
    final OnBoardingPageController onBoardingPageController =
        Get.put(OnBoardingPageController());
    return Scaffold(
      /* <-------- Content --------> */
      body: SafeArea(
        top: false,
        child: Stack(
          children: [
            /// Center right bubble
            Positioned(
              top: 270,
              right: -100,
              child: Image.asset(AppAssetImages.lightBubbleTr),
            ),

            /// Top left bubble
            Positioned(
              top: -110,
              left: -120,
              child: Image.asset(AppAssetImages.blueBubbleTl),
            ),

            /// Introduction pages
            PageView.builder(
              controller: onBoardingPageController.pageController,
              onPageChanged: onBoardingPageController.updatePageIndicator,
              scrollDirection: Axis.horizontal,
              itemCount: OnboardingPageContents.onboardingContents.length,
              itemBuilder: (context, index) {
                /// Single intro screen data
                final introContent =
                    OnboardingPageContents.onboardingContents[index];
                /* <---- Single Intro screen widget ----> */
                return
                IntroContentWidget(
                    imagePath: introContent.imagePath,
                    slogan: introContent.slogan,
                    subtitle: introContent.subtitle);
              },
            ),

            /// Current Page Dot Indicator
            Positioned(
              left: 0,
              right: 0,
              bottom: AppDeviceUtility.getBottomNavigationBarHeight() + 25,
              child: Center(
                child: SmoothPageIndicator(
                  controller: onBoardingPageController.pageController,
                  count: OnboardingPageContents.onboardingContents.length,
                  axisDirection: Axis.horizontal,
                  effect: ExpandingDotsEffect(
                    dotHeight: 15,
                    dotWidth: 15,
                    spacing: 5,
                    expansionFactor: 3,
                    activeDotColor: AppColors.primaryColor,
                    dotColor: AppColors.darkColor.withOpacity(0.2),
                  ),
                ),
              ),
            )
          ],
        ),
      ),

      /// Next Button
      floatingActionButton: FloatingActionButton(
        shape: const CircleBorder(),
        foregroundColor: Colors.white,
        backgroundColor: AppColors.primaryColor,
        onPressed: () {
          onBoardingPageController.nextPage();
        },
        child: const Icon(
          Icons.keyboard_arrow_right,
          size: 35,
        ),
      ),
    );
  }
}

Here is the on boarding controller code:

class OnBoardingPageController extends GetxController {
  static OnBoardingPageController get instance => Get.find();

  // Variables
  final PageController pageController = PageController();
  final RxInt currentIndex = 0.obs;

  // Update current index when page scrolls
  void updatePageIndicator (index) => currentIndex.value = index;

  // Next button function
  void nextPage () {
    if(currentIndex.value == OnboardingPageContents.onboardingContents.length - 1){
      Get.to(() => ContinueWithGooglePage());
    } else {
      int page = currentIndex.value + 1;
      pageController.jumpToPage(page);
    }
  }

The pageController works if I use a simply use a pageController in the same class and the page indicator updates, but I want to use Getx. I also have issue with the next button. I have put the right codes but it still doen’s work. Please check the above code.

2

Answers


  1. Try to Wrap indicator widget with Obx

    Obx(()=> IndicatorWidget())
    

    I think it didn’t update because i didn’t see Obx in your code maybe that why it didn’t observe

    Login or Signup to reply.
  2. class OnBoardingPage extends StatelessWidget {
      const OnBoardingPage({super.key});
    
      @override
      Widget build(BuildContext context) {
        final OnBoardingPageController onBoardingPageController = Get.put(OnBoardingPageController());
        return Scaffold(
          body: SafeArea(
            top: false,
            child: Stack(
              children: [
                // Center right bubble
                Positioned(
                  top: 270,
                  right: -100,
                  child: Image.asset(AppAssetImages.lightBubbleTr),
                ),
                // Top left bubble
                Positioned(
                  top: -110,
                  left: -120,
                  child: Image.asset(AppAssetImages.blueBubbleTl),
                ),
                // Introduction pages
                PageView.builder(
                  controller: onBoardingPageController.pageController,
                  onPageChanged: onBoardingPageController.updatePageIndicator,
                  scrollDirection: Axis.horizontal,
                  itemCount: OnboardingPageContents.onboardingContents.length,
                  itemBuilder: (context, index) {
                    final introContent = OnboardingPageContents.onboardingContents[index];
                    return IntroContentWidget(
                      imagePath: introContent.imagePath,
                      slogan: introContent.slogan,
                      subtitle: introContent.subtitle,
                    );
                  },
                ),
                // Current Page Dot Indicator
                Positioned(
                  left: 0,
                  right: 0,
                  bottom: AppDeviceUtility.getBottomNavigationBarHeight() + 25,
                  child: Center(
                    child: Obx(() => SmoothPageIndicator(
                      controller: onBoardingPageController.pageController,
                      count: OnboardingPageContents.onboardingContents.length,
                      axisDirection: Axis.horizontal,
                      effect: ExpandingDotsEffect(
                        dotHeight: 15,
                        dotWidth: 15,
                        spacing: 5,
                        expansionFactor: 3,
                        activeDotColor: AppColors.primaryColor,
                        dotColor: AppColors.darkColor.withOpacity(0.2),
                      ),
                    )),
                  ),
                ),
              ],
            ),
          ),
          // Next Button
          floatingActionButton: FloatingActionButton(
            shape: const CircleBorder(),
            foregroundColor: Colors.white,
            backgroundColor: AppColors.primaryColor,
            onPressed: () {
              onBoardingPageController.nextPage();
            },
            child: const Icon(
              Icons.keyboard_arrow_right,
              size: 35,
            ),
          ),
        );
      }
    }
    

    class OnBoardingPageController extends GetxController {
      static OnBoardingPageController get instance => Get.find();
    
      // Variables
      final PageController pageController = PageController();
      final RxInt currentIndex = 0.obs;
    
      // Update current index when page scrolls
      void updatePageIndicator(int index) {
        currentIndex.value = index;
      }
    
      // Next button function
      void nextPage() {
        if (currentIndex.value == OnboardingPageContents.onboardingContents.length - 1) {
          Get.to(() => ContinueWithGooglePage());
        } else {
          int page = currentIndex.value + 1;
          pageController.animateToPage(
            page,
            duration: Duration(milliseconds: 300),
            curve: Curves.easeIn,
          );
        }
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search