Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

I have a RangeError Error in my flutter Project. How do I sort this out?

I have an onboarding screen that I am working on. The onboarding screen navigates to the next page after 300 milliseconds. But the problem I have is that there is a part of the screen that has refused to work properly. The first page appears and display all the images and other contents. But when it tries to navigates to the next screen, it displays a red background color with an error

RangeError (index): invalid value: Only valid value is 0 : 2, see also…

I have tried to resolve this myself but to no avail.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

This is my onboarding screen code.

import 'package:flutter/material.dart';
import 'package:greenbii_app/constants/constants.dart';
import 'package:greenbii_app/onboarding/onboarding_data.dart';
import 'package:greenbii_app/onboarding/onboarding_page.dart';
import 'package:greenbii_app/onboarding/onboarding_page_indicator.dart';
import 'dart:async';

class OnboardingScreen extends StatefulWidget {
  const OnboardingScreen({Key? key}) : super(key: key);

  @override
  State<OnboardingScreen> createState() => _OnboardingScreenState();
}

class _OnboardingScreenState extends State<OnboardingScreen> {
  int currentPageIndex = 0;
  final PageController _pageController = PageController();
  Timer? _pageTimer;

  @override
  void initState() {
    super.initState();
    _startTimer();
  }

  @override
  void dispose() {
    _pageTimer?.cancel();
    _pageController.dispose();
    super.dispose();
  }

  void _startTimer() {
    _pageTimer = Timer.periodic(const Duration(seconds: 5), (timer) {
      if (currentPageIndex < onboardingData.length - 1) {
        _pageController.nextPage(
          duration: const Duration(milliseconds: 300),
          curve: Curves.easeInOut,
        );
      }
    });
  }

  void _stopTimer() {
    _pageTimer?.cancel();
  }

  void _navigateToNextPage() {
    if (currentPageIndex < onboardingData.length - 1) {
      _pageController.nextPage(
        duration: const Duration(milliseconds: 300),
        curve: Curves.easeInOut,
      );
    } else {
      // Navigate to the login and registration screen
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: AppColors.onboardingColorBG,
        body: SafeArea(
          child: Column(children: [
            Expanded(
              child: PageView.builder(
                controller: _pageController,
                onPageChanged: (index) {
                  setState(() { 
                    currentPageIndex = index;
                  });
                },
                itemCount: onboardingData.length,
                itemBuilder: (context, int index) {
                  return OnboardingPage(
                    data: onboardingData[index],
                    index: index,
                    currentPageIndex: currentPageIndex,
                    onStopTimer: _stopTimer,
                    onNextPage: _navigateToNextPage,
                    pageController: _pageController,
                  );
                },
              ),
            ),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 30),
              child: Row(
                children: [
                  OnboardingPageIndicator(
                    currentPageIndex: currentPageIndex,
                    totalPages: onboardingData.length,
                  ),
                  const Spacer(),
                  TextButton(
                    onPressed: () {
                      // Navigate to the login Page
                    },
                    child: Row(children: const [
                      Text(
                        'Skip',
                        style: TextStyle(
                            color: AppColors.primaryColor, fontSize: 16),
                      ),
                      Icon(
                        Icons.chevron_right,
                        color: AppColors.primaryColor,
                      )
                    ]),
                  )
                ],
              ),
            ),
            const SizedBox(
              height: 20,
            ),
          ]),
        ));
  }
}

I have used Page.View Widget but the whole screen content disappears when I use it, and without it, it gives the error above.

This is my onboarding page widget that I reused in the onboarding screen

import 'package:flutter/material.dart';
import 'package:greenbii_app/constants/constants.dart';
import 'package:greenbii_app/onboarding/onboarding_data.dart';
// import 'package:google_fonts/google_fonts.dart';

class OnboardingPage extends StatelessWidget {
  final OnboardingData data;
  final int index;
  final int currentPageIndex;
  final VoidCallback onStopTimer;
  final VoidCallback onNextPage;
  final PageController? pageController;

  const OnboardingPage({
    Key? key,
    required this.data,
    required this.index,
    required this.currentPageIndex,
    required this.onStopTimer,
    required this.onNextPage,
    this.pageController,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        SizedBox(
          height: 300,
          child: Image.asset(
            data.imagePath[currentPageIndex],
          ),
        ),
        //
        Padding(
          padding: const EdgeInsets.all(20.0),
          child: Column(
            children: [
              Text(
                data.title,
                style: const TextStyle(
                  fontSize: 20,
                  fontWeight: FontWeight.bold,
                  color: AppColors.primaryColor,
                ),
                textAlign: TextAlign.center,
              ),
              const SizedBox(
                height: 10,
              ),
              Text(
                data.bodyText,
                style: const TextStyle(
                  fontSize: 14,
                  fontWeight: FontWeight.normal,
                  color: AppColors.primaryColor,
                ),
                textAlign: TextAlign.center,
              )
            ],
          ),
        ),
        const SizedBox(
          height: 30,
        ),
        Padding(
          padding: const EdgeInsets.symmetric(horizontal: 70),
          child: Container(
            width: double.infinity, // Width takes up 100% of the device
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(50.0), // Add border radius
              gradient: const LinearGradient(
                colors: [
                  AppColors.primaryColorLow,
                  AppColors.primaryColor,
                ],
                begin: Alignment.topLeft,
                end: Alignment.bottomRight,
              ),
            ),
            child: ElevatedButton(
              onPressed: () {
                onNextPage();
              },
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors
                    .transparent, // Make the button background transparent
                shadowColor: Colors.transparent, // Remove the default shadow
              ),
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Text(
                  currentPageIndex == onboardingData.length - 1
                      ? "Get Started"
                      : "Continue",
                  style: const TextStyle(color: Colors.white),
                ),
              ),
            ),
          ),
        ),
      ],
    );
  }
}

Also below is my onboardingdata file, probably something is wrong the way I used it.

class OnboardingData {
  final List<String> imagePath;
  final String title;
  final String bodyText;

  OnboardingData(this.imagePath, this.title, this.bodyText);
}

List<OnboardingData> onboardingData = [
  OnboardingData(
    ["assets/images/onboarding_img1.png"],
    "Grow Your Business!",
    "Access all the digital and financial resources you need, all in one place.",
  ),
  OnboardingData(
    ["assets/images/onboarding_img2.png"],
    "Manage all from one dashboard.",
    "Your GreenBii account allows you manage all your softwares and monitor all your devices from one place.",
  ),
  OnboardingData(
    ["assets/images/onboarding_img3.png"],
    "Welcome, Let’s Get Started",
    "Get \$10 free GreenBii Credit when you create an account.",
  ),
];

How to get this solved?

>Solution :

On your onboardingData list, take a look at every imagePath argument:

List<OnboardingData> onboardingData = [
  OnboardingData(
    ["assets/images/onboarding_img1.png"],
    "Grow Your Business!",
    "Access all the digital and financial resources you need, all in one place.",
  ),
  OnboardingData(
    ["assets/images/onboarding_img2.png"],
    "Manage all from one dashboard.",
    "Your GreenBii account allows you manage all your softwares and monitor all your devices from one place.",
  ),
  OnboardingData(
    ["assets/images/onboarding_img3.png"],
    "Welcome, Let’s Get Started",
    "Get \$10 free GreenBii Credit when you create an account.",
  ),
];

They are all a list of strings with a single element. When you do

SizedBox(
  height: 300,
  child: Image.asset(
    data.imagePath[currentPageIndex],
  ),
),

and currentPageIndex == 2, for example, you are accessing more than a single element on that list.

So you may either

  • change it to data.imagePath[0] (the quickest way to solve this)
  • change imagePath‘s type from List<String> to a String, and use it as data.imagePath
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading