skip to Main Content

I am trying to implement a carousel indicator with my CarouselView but i am unable to get the current index. My code is as below:

class WelcomeScreen extends ConsumerStatefulWidget {
  const WelcomeScreen({super.key});

  @override
  ConsumerState<WelcomeScreen> createState() => WelcomeScreenState();
}

class WelcomeScreenState extends ConsumerState<WelcomeScreen> {
  int currentIndex = 0;
  final carouselController = CarouselController();

  @override
  void initState() {
    super.initState();
    carouselController.addListener(() {
      // Set the current index here
    });
  }

// Don't forget to dispose
  @override
  void dispose() {
    carouselController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final scaffoldKey = GlobalKey<ScaffoldState>();
    final theme = Theme.of(context);

    return Scaffold(
      key: scaffoldKey,
      body: SingleChildScrollView(
        scrollDirection: Axis.vertical,
        child: SafeArea(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              SizedBox(
                height: 240,
                child: CarouselView(
                  controller: carouselController,
                  padding: EdgeInsets.all(12.0),
                  itemExtent: MediaQuery.sizeOf(context).width,
                  itemSnapping: true,
                  children: List.generate(5, (index) {
                    setState(() {
                      currentIndex = index;
                    });
                    return Container(
                      color: theme.colorScheme.surfaceContainer,
                    );
                  }),
                ),
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: List.generate(5, (index) {
                  return AnimatedContainer(
                    duration: const Duration(milliseconds: 300),
                    margin: const EdgeInsets.symmetric(horizontal: 4),
                    height: 8,
                    width:
                        currentIndex == index ? 24 : 8, // Make active dot wider
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(4),
                      color: currentIndex == index
                          ? theme.colorScheme.primary
                          : theme.colorScheme.tertiary,
                    ),
                  );
                }),
              )
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        elevation: MesElevation.fab,
        backgroundColor: theme.colorScheme.primary,
        foregroundColor: theme.colorScheme.onPrimary,
        onPressed: () {},
        shape: CircleBorder(),
        child: Icon(Icons.arrow_forward_ios_outlined),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
    );
  }
}

I see that there is a position attribute in the controller but it returns the ScrollPosition type and i don’t know how to get the index from this to update my indicator view.

Any one can help please?

2

Answers


  1. Do something like this to the CarouselController listener,

           controller.addListener(() {
                final position = controller.position;
                final width = MediaQuery.sizeOf(context).width - 32; //your width
                if (position.hasPixels) {
                  final index = (position.pixels / width).round();
                  setState(() {
                    currentIndex.value = index;
                  });
                }
              });
    

    Rest of the stuff you’ve write seems good to go!

    I personally prefer in this case, making a Mixin that has other logic like

    • Auto scrolling
    • Current Index (etc)
    Login or Signup to reply.
  2.        CarouselSlider(
                      carouselController: carouselController,
                      options: CarouselOptions(
                        height: 240,
                        onPageChanged: (index, reason) {
                          setState(() {
                            currentIndex = index; 
                          });
                        },
                      ),
                      items: List.generate(5, (index) {
                        return Container(
                          color: theme.colorScheme.surfaceContainer,
                          child: Center(child: Text('Item $index')), 
                        );
                      }),
                    ),
                  ),
            floatingActionButton: FloatingActionButton(
            elevation: 6,
            backgroundColor: theme.colorScheme.primary,
            foregroundColor: theme.colorScheme.onPrimary,
            onPressed: () {
            
              if (currentIndex < 4) {
                carouselController.nextPage();
              }
            },
            shape: CircleBorder(),
            child: Icon(Icons.arrow_forward_ios_outlined),
          ),
          floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
        );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search