[FIXED] How to make a Custom Carousell flutter

Issue

Found this on cool carousell UI on
dribble

I really wanted to make something like this but don’t know where to start

Any Ideas would be greatly appreciated

Thanks!!

fafa

Solution

It can be done easily with cuasual package, or you can also achieve it by using PageView.

Here is an example:

  • PageView: show 1 page and see the previous/next page by setting viewportFraction
  • AnimatedBuilder: listen to the change of page offset
  • Transform: scale, rotate and translation the position of next, previous page

code:

import 'package:flutter/material.dart';
import 'dart:math' as math;

const viewportFraction = 0.7;

class MyPageView extends StatefulWidget {
  const MyPageView({
    required this.children,
    Key? key,
  }) : super(key: key);

  final List<Widget> children;

  factory MyPageView.images(List<ImageProvider> imageProviders) {
    return MyPageView(
      children: [
        for (final image in imageProviders)
          ClipRRect(
            borderRadius: BorderRadius.circular(16),
            child: Image(
              image: image,
              fit: BoxFit.cover,
            ),
          ),
      ],
    );
  }

  @override
  State<MyPageView> createState() => _MyPageViewState();
}

class _MyPageViewState extends State<MyPageView> {
  final pageController = PageController(viewportFraction: viewportFraction);

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraint) {
        final maxWidth = constraint.maxWidth;
        return PageView.builder(
          allowImplicitScrolling: true,
          controller: pageController,
          itemCount: widget.children.length,
          itemBuilder: (_, index) {
            final child = widget.children[index];
            return AnimatedBuilder(
              animation: pageController,
              builder: (_, __) {
                final ratioX = pageController.offset / maxWidth / viewportFraction - index;

                return Transform.rotate(
                  angle: math.pi * -0.05 * ratioX,
                  child: Transform.translate(
                    offset: Offset(ratioX * 10, ratioX.abs() * 70),
                    child: Transform.scale(
                      scale: 0.8,
                      child: child,
                    ),
                  ),
                );
              },
            );
          },
        );
      },
    );
  }

  @override
  void dispose() {
    pageController.dispose();
    super.dispose();
  }
}

And here is the example result:

MyPageView.images(
  List.generate(
    50,
     (index) => NetworkImage('https://picsum.photos/seed/$index/400/600'),
    ),
  )

enter image description here

Answered By – yellowgray

Answer Checked By – Clifford M. (Easybugfix Volunteer)

Leave a Reply

(*) Required, Your email will not be published