Search code examples
flutterflutter-animation

Page swipe behaviour with AnimatedSwitcher and Dismissible


I'm trying to achieve the $subject. When I do the swipe to the left side(movement is right -> left) animation happens properly and widget starts from the right side and stay. But when I do the swipe to the right side, widget transition is happening but the widget starts to appear from the right side instead of the left side.

I'm trying to achieve swipe move like normally do in calendar.

enter image description here

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MainPage(),
    );
  }
}

class MainPage extends StatefulWidget {
  @override
  _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  Widget child;

  @override
  void initState() {
    super.initState();
    child = Container(
      child: Center(
        child: Text(
          'Main',
          style: TextStyle(fontSize: 18.0),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: AnimatedSwitcher(
        duration: const Duration(milliseconds: 350),
        switchInCurve: Curves.easeIn,
        switchOutCurve: Curves.easeOut,
        transitionBuilder: (child, animation) {
          return SlideTransition(
            position: Tween<Offset>(begin: Offset(1.2, 0), end: Offset(0, 0))
                .animate(animation),
            child: child,
          );
        },
        layoutBuilder: (currentChild, _) => currentChild,
        child: Dismissible(
          key: UniqueKey(),
          resizeDuration: null,
          onDismissed: _onHorizontalSwipe,
          direction: DismissDirection.horizontal,
          child: child,
        ),
      ),
    );
  }

  void _onHorizontalSwipe(DismissDirection direction) {
    if (direction == DismissDirection.startToEnd) {
      setState(() {
        child = Page1();
      });
    } else {
      setState(() {
        child = Page2();
      });
    }
  }
}

class Page1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.yellow,
      child: Center(
        child: Text(
          'Left side page',
          style: TextStyle(fontSize: 18.0),
        ),
      ),
    );
  }
}

class Page2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.blueAccent,
      child: Center(
        child: Text(
          'Right side page',
          style: TextStyle(fontSize: 18.0),
        ),
      ),
    );
  }
}


Solution

  • You probably got it already but, your animation values in transitionbuilder will always run from 0 to 1, so you always get the same transition. You gotta set a swipe left or right condition.