swipable_stack 0.6.2 copy "swipable_stack: ^0.6.2" to clipboard
swipable_stack: ^0.6.2 copied to clipboard

outdated

A widget for stacking cards, which users can swipe horizontally and vertically with beautiful animations.

example/lib/main.dart

import 'dart:math';

import 'package:example/card_label.dart';
import 'package:flutter/material.dart';
import 'package:swipable_stack/swipable_stack.dart';

class SwipeDirectionColor {
  static const right = Color.fromRGBO(70, 195, 120, 1);
  static const left = Color.fromRGBO(220, 90, 108, 1);
  static const up = Color.fromRGBO(83, 170, 232, 1);
  static const down = Color.fromRGBO(154, 85, 215, 1);
}

extension SwipeDirecionX on SwipeDirection {
  Color get color {
    switch (this) {
      case SwipeDirection.right:
        return Color.fromRGBO(70, 195, 120, 1);
      case SwipeDirection.left:
        return Color.fromRGBO(220, 90, 108, 1);
      case SwipeDirection.up:
        return Color.fromRGBO(83, 170, 232, 1);
      case SwipeDirection.down:
        return Color.fromRGBO(154, 85, 215, 1);
    }
    return Colors.transparent;
  }
}

const _images = [
  'images/image_5.jpg',
  'images/image_3.jpg',
  'images/image_4.jpg',
];

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Home(),
    );
  }
}

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

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  SwipableStackController _controller;

  void _listenController() {
    setState(() {});
  }

  @override
  void initState() {
    super.initState();
    _controller = SwipableStackController()..addListener(_listenController);
  }

  static const double _bottomAreaHeight = 100;

  static const EdgeInsets _padding = EdgeInsets.all(16);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('currentIndex:${_controller.currentIndex}'),
      ),
      body: SafeArea(
        child: Column(
          children: [
            Expanded(
              child: SwipableStack(
                controller: _controller,
                stackClipBehaviour: Clip.none,
                onSwipeCompleted: (index, direction) {
                  print('$index, $direction');
                },
                overlayBuilder: (
                  context,
                  constraints,
                  index,
                  direction,
                  swipeProgress,
                ) {
                  final opacity = min(swipeProgress, 1.0);

                  final isRight = direction == SwipeDirection.right;
                  final isLeft = direction == SwipeDirection.left;
                  final isUp = direction == SwipeDirection.up;
                  final isDown = direction == SwipeDirection.down;
                  return Padding(
                    padding: _padding * 3,
                    child: Stack(
                      children: [
                        Opacity(
                          opacity: isRight ? opacity : 0,
                          child: CardLabel.right(),
                        ),
                        Opacity(
                          opacity: isLeft ? opacity : 0,
                          child: CardLabel.left(),
                        ),
                        Opacity(
                          opacity: isUp ? opacity : 0,
                          child: CardLabel.up(),
                        ),
                        Opacity(
                          opacity: isDown ? opacity : 0,
                          child: CardLabel.down(),
                        ),
                      ],
                    ),
                  );
                },
                builder: (context, index, constraints) {
                  final imagePath = _images[index % _images.length];
                  return Padding(
                    padding: _padding,
                    child: Center(
                      child: LayoutBuilder(
                        builder: (context, constraints) {
                          return Image.asset(
                            imagePath,
                            height: constraints.maxHeight,
                          );
                        },
                      ),
                    ),
                  );
                },
              ),
            ),
            SizedBox(
              height: _bottomAreaHeight,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  _BottomButton(
                    color: _controller.canRewind
                        ? Colors.amberAccent
                        : Colors.grey,
                    child: const Icon(Icons.refresh),
                    onPressed: _controller.canRewind
                        ? () {
                            _controller.rewind();
                          }
                        : null,
                  ),
                  _BottomButton(
                    color: SwipeDirectionColor.left,
                    child: const Icon(Icons.arrow_back),
                    onPressed: () {
                      _controller.next(
                        swipeDirection: SwipeDirection.left,
                      );
                    },
                  ),
                  _BottomButton(
                    color: SwipeDirectionColor.up,
                    onPressed: () {
                      _controller.next(
                        swipeDirection: SwipeDirection.up,
                      );
                    },
                    child: const Icon(Icons.arrow_upward),
                  ),
                  _BottomButton(
                    color: SwipeDirectionColor.right,
                    onPressed: () {
                      _controller.next(
                        swipeDirection: SwipeDirection.right,
                      );
                    },
                    child: const Icon(Icons.arrow_forward),
                  ),
                  _BottomButton(
                    color: SwipeDirectionColor.down,
                    onPressed: () {
                      _controller.next(
                        swipeDirection: SwipeDirection.down,
                      );
                    },
                    child: const Icon(Icons.arrow_downward),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    _controller.removeListener(_listenController);
    _controller.dispose();
  }
}

class _BottomButton extends StatelessWidget {
  const _BottomButton({
    Key key,
    @required this.onPressed,
    @required this.child,
    @required this.color,
  }) : super(key: key);

  final VoidCallback onPressed;
  final Icon child;
  final Color color;

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: 64,
      width: 64,
      child: ElevatedButton(
        style: ButtonStyle(
          shape: MaterialStateProperty.resolveWith(
            (states) => RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(100),
            ),
          ),
          backgroundColor: MaterialStateProperty.resolveWith(
            (states) => color,
          ),
        ),
        onPressed: onPressed,
        child: child,
      ),
    );
  }
}
309
likes
0
points
3.76k
downloads

Publisher

verified publisherheavenosk.com

Weekly Downloads

A widget for stacking cards, which users can swipe horizontally and vertically with beautiful animations.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter

More

Packages that depend on swipable_stack