How do I make DotIndicator Responsive?

Viewed 42

I want to make dot indicator move along with the image as the window is stretched to adjust to bigger screens and smaller screens?

I have used MediaQuery but it doesn't really solve my problem. I want it to smoothly adjust to the image as its aspect Ratio changes for which I have used Media Query.

import 'package:flutter/material.dart';

class ImageCarousel extends StatefulWidget {
  const ImageCarousel({super.key});

  @override
  State<ImageCarousel> createState() => _ImageCarouselState();
}

class _ImageCarouselState extends State<ImageCarousel> {
  int _currentPage = 0;

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;

    return AspectRatio(
      aspectRatio: size.aspectRatio * 3,
      child: Stack(
        alignment: Alignment.bottomRight,
        children: [
          PageView.builder(
            onPageChanged: (value) {
              setState(() => _currentPage = value);
            },
            itemCount: demoBigImages.length,
            itemBuilder: (context, i) => ClipRRect(
              borderRadius: const BorderRadius.all(
                Radius.circular(12),
              ),
              child: Image.asset(
                demoBigImages[i],
              ),
            ),
          ),
          Positioned(
            bottom: size.height * 0.04,
            right: size.width * 0.04,
            child: Row(
              children: List.generate(
                demoBigImages.length,
                (index) => Padding(
                  padding: const EdgeInsets.all(defaultPadding / 4.5),
                  child: IndicatorDot(
                    isActive: index == _currentPage,
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}
class IndicatorDot extends StatelessWidget {
  final bool isActive;

  const IndicatorDot({super.key, required this.isActive});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 8,
      height: 4,
      decoration: BoxDecoration(
        color: isActive ? Colors.red : Colors.red.shade50,
        borderRadius: const BorderRadius.all(
          Radius.circular(12),
        ),
      ),
    );
  }
}
2 Answers

Try to use the margins in the dot indicator widget with media query not hard code values.

Use it like

margin: EdgeInsets.all(MediaQuery.of(context).size.width*0.02),

To move the indicator dot alongside the PageView scrolling transition you'd need to move the Stack to the itemBuilder.

It's going to be something like bellow. Notice the commented lines:

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

  @override
  State<ImageCarousel> createState() => _ImageCarouselState();
}

class _ImageCarouselState extends State<ImageCarousel> {
  int _currentPage = 0;

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;

    return AspectRatio(
      aspectRatio: size.aspectRatio * 3,
      child: PageView.builder(
        onPageChanged: (value) {
          setState(() => _currentPage = value);
        },
        itemCount: 'demoBigImages.length'.length,
        itemBuilder: (context, i) => Stack(            // <- Here
          children: [
            ClipRRect(
              borderRadius: const BorderRadius.all(
                Radius.circular(12),
              ),
              child: Image.asset(
                'demoBigImages[i]',
              ),
            ),
            Positioned(                                // <- Here
              bottom: size.height * 0.04,
              right: size.width * 0.04,
              child: Row(
                children: List.generate(
                  'demoBigImages'.length,
                  (index) => Padding(
                    padding: const EdgeInsets.all(defaultPadding / 4.5),
                    child: IndicatorDot(
                      isActive: index == _currentPage,
                    ),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
Related