skip to Main Content

I want to achieve this kind of swipe image 1

But when i deisgned i am getting this kind of output image 2

I want the smoothness while swiping and don’t want to use any packages.

Any suggestion or help is appriciated.

I have tries using Transfor.rotate but there is no animation the reaults i got you can see above

import 'package:flutter/material.dart';
import 'package:mawada/cardCollections/widgets/card_play_widget.dart';
import 'package:mawada/constants/app_color.dart';
import 'package:mawada/shared/widgets/app_button.dart';

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

  @override
  State<CardPlay> createState() => _CardPlayState();
}

class _CardPlayState extends State<CardPlay>
    with SingleTickerProviderStateMixin {
  final pageController = PageController(viewportFraction: 0.7);
  int _index = 0;
  late final AnimationController _animationController;

  int currentPage = 0;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 500),
    );
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: AppColor.background,
        appBar: AppBar(
          actions: [
            Padding(
              padding: const EdgeInsets.only(right: 10.0),
              child: Image.asset(
                'assets/logo2.png',
                fit: BoxFit.cover,
                height: 55,
              ),
            )
          ],
        ),
        body: ListView(
          padding: const EdgeInsets.symmetric(vertical: 30),
          children: [
            // Progress indiator
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 20),
              child: Container(
                decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.circular(30),
                    boxShadow: [
                      BoxShadow(
                          offset: const Offset(0, 2),
                          color: Colors.grey.withOpacity(0.5),
                          spreadRadius: 1,
                          blurRadius: 2)
                    ]),
                child: LinearProgressIndicator(
                    value: 0.2,
                    semanticsLabel: "0.2",
                    backgroundColor: Colors.white,
                    valueColor: const AlwaysStoppedAnimation<Color>(
                      AppColor.primary,
                    ),
                    minHeight: 45,
                    borderRadius: BorderRadius.circular(30)),
              ),
            ),
            const SizedBox(
              height: 50,
            ),
            SizedBox(
              height: 400,
              child: PageView.builder(
                  // physics: PageScrollPhysics(),
                  onPageChanged: (int index) => setState(() => _index = index),
                  controller: pageController,
                  itemCount: 10,
                  itemBuilder: (context, i) {
                    final double rotation = (i - _index) == 1
                        ? 0.1
                        : (i - _index) == -1
                            ? -0.1
                            : 0.0;
                    return Center(
                        child: Transform.rotate(
                            filterQuality: FilterQuality.low,
                            angle: i == _index ? 0 : rotation,
                            // angle: i == currentPage ? _animationController.value * rotation : rotation,
                            child: i == _index
                                ? const Padding(
                                    padding: EdgeInsets.only(bottom: 30),
                                    child: CardPlayWidget(),
                                  )
                                : const CardPlayWidget()));
                  }),
            )
          ],
        ),
        bottomNavigationBar: Container(
          height: 150,
          padding: const EdgeInsets.symmetric(horizontal: 20),
          child: Center(
              child: AppButton(
                  elevation: 0,
                  borderSideColor: AppColor.primary,
                  backgroundColor: AppColor.background,
                  foregroundColor: AppColor.primary,
                  buttonText: "Close",
                  onPressed: () {})),
        ));
  }
}

This is the code i have written

2

Answers


  1. You can use PageController along with GestureDetector and make PageView’s physics to NeverScrollableScrollPhysics. Try below once it may need some improvements according to your need :

    Scaffold(
        appBar: AppBar(
          backgroundColor: Theme.of(context).colorScheme.inversePrimary,
          title: Text(widget.title),
        ),
        body: GestureDetector(
          onHorizontalDragUpdate: (val) {
            if(val.globalPosition.dx < MediaQuery.of(context).size.width / 2) {
              controller.nextPage(duration: Duration(seconds: 3), curve: Curves.elasticOut);
            } else {
              controller.previousPage(duration: Duration(seconds: 3), curve: Curves.elasticOut);
            }
          },
          child: PageView.builder(
            itemCount: 10,
              controller:controller ,
              physics: NeverScrollableScrollPhysics(),
              itemBuilder: (context,index) => AnimatedContainer(
            height: 200, width: 150,
            margin: EdgeInsets.symmetric(horizontal: 20),
            color: Colors.red,
            duration: Duration(milliseconds: 600),
            child: Text("$index"),
          )),
        ),
    )
    
    Login or Signup to reply.
  2. try this Foo widget, the main idea is to use Flow widget with a delegate that paints the rotated child:

    class Foo extends StatelessWidget {
      final ctrl = PageController(
        viewportFraction: 0.6,
      );
      @override
      Widget build(BuildContext context) {
        return AspectRatio(
          aspectRatio: 1.25,
          child: ColoredBox(
            color: Colors.blue.shade900,
            child: PageView.builder(
              controller: ctrl,
              clipBehavior: Clip.none,
              itemCount: 10,
              itemBuilder: (ctx, i) {
                return Flow(
                  clipBehavior: Clip.none,
                  delegate: FooDelegate(i, ctrl),
                  children: [
                    Card(
                      color: Colors.orange,
                      elevation: 4,
                      child: FittedBox(child: Text('$i')),
                    ),
                  ],
                );
              },
            ),
          ),
        );
      }
    }
    
    class FooDelegate extends FlowDelegate {
      FooDelegate(this.page, this.ctrl) : super(repaint: ctrl);
    
      final int page;
      final PageController ctrl;
    
      @override
      void paintChildren(FlowPaintingContext context) {
        final delta = page - ctrl.page!;
        final angle = 0.075 * pi * delta;
        final size = context.getChildSize(0)!;
        final offset = Offset((1 - delta) * size.width * 0.5, 1.0 * size.height);
        final transform = composeMatrixFromOffsets(
          rotation: angle,
          anchor: offset,
          translate: offset,
        );
        context.paintChild(0, transform: transform);
      }
    
      @override
      bool shouldRepaint(covariant FlowDelegate oldDelegate) => false;
    }
    
    Matrix4 composeMatrixFromOffsets({
      double scale = 1,
      double rotation = 0,
      Offset translate = Offset.zero,
      Offset anchor = Offset.zero,
    }) {
      final double c = cos(rotation) * scale;
      final double s = sin(rotation) * scale;
      final double dx = translate.dx - c * anchor.dx + s * anchor.dy;
      final double dy = translate.dy - s * anchor.dx - c * anchor.dy;
      return Matrix4(c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, 0, dx, dy, 0, 1);
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search