flutter_slidable icon indicating copy to clipboard operation
flutter_slidable copied to clipboard

Animate the slidable slightly to show the hidden feature

Open sarbogast opened this issue 4 years ago • 9 comments

I love Slidable, but swipe buttons are hidden and I'm looking for ways to show the user those buttons in a showcase. I'm using showcaseview to show overlays for important buttons in the app, but in the case of swipe buttons, I can only show an overlay on the first ListTile in a ListView explaining actions that are available behind a swipe right. It would be much more powerful to be able to animate the Slidable to uncover the slidable actions slightly, to show that there is something hidden behind this ListTile. Is it possible to do that, maybe with a SlidableController? If so, could you please document how to do it?

sarbogast avatar Dec 22 '21 16:12 sarbogast

I would like this feature too 😁

luciano-cervantes avatar Dec 30 '21 16:12 luciano-cervantes

A very important and desired feature would be this!

ramvdixit avatar Jan 03 '22 07:01 ramvdixit

This is what I'm doing

slidable?.openEndActionPane(
  duration: const Duration(milliseconds: 500),
  curve: Curves.decelerate,
);

Future.delayed(const Duration(seconds: 1), () {
  slidable?.close(
    duration: const Duration(milliseconds: 500),
    curve: Curves.bounceInOut,
  );
});

austinn avatar Jan 25 '22 14:01 austinn

@austinn and how do you build the slidable reference? With a GlobalKey?

sarbogast avatar Jan 25 '22 15:01 sarbogast

@austinn and how do you build the slidable reference? With a GlobalKey?

Using his code, I made this:

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

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

class MyApp extends StatelessWidget {
  const MyApp({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) => MaterialApp(
    title: 'Slidable Example',
    home: Scaffold(
      body: SafeArea(
        child: Slidable(
          startActionPane: ActionPane(
            motion: const ScrollMotion(),
            dismissible: DismissiblePane(onDismissed: () {}),
            children: const [
              SlidableAction(
                onPressed: doNothing,
                backgroundColor: Color(0xFFFE4A49),
                foregroundColor: Colors.white,
                icon: Icons.delete,
                label: 'Delete',
              ),
              SlidableAction(
                onPressed: doNothing,
                backgroundColor: Color(0xFF21B7CA),
                foregroundColor: Colors.white,
                icon: Icons.share,
                label: 'Share',
              ),
            ],
          ),
          endActionPane: const ActionPane(
            motion: ScrollMotion(),
            children: [
              SlidableAction(
                flex: 2,
                onPressed: doNothing,
                backgroundColor: Color(0xFF7BC043),
                foregroundColor: Colors.white,
                icon: Icons.archive,
                label: 'Archive',
              ),
              SlidableAction(
                onPressed: doNothing,
                backgroundColor: Color(0xFF0392CF),
                foregroundColor: Colors.white,
                icon: Icons.save,
                label: 'Save',
              ),
            ],
          ),
          child: SlidableTile()
        ),
      ),
    ),
  );
}

void doNothing(BuildContext context) {}

class SlidableTile extends StatefulWidget {
  _SlidableTile createState() => _SlidableTile();
}

class _SlidableTile extends State<SlidableTile> {

  @override
  void initState() {
    super.initState();
    _start();
  }

  // the magic is here
  Future<void> _start() async {
    await Future<void>.delayed(const Duration(seconds: 1));
    var slidable = Slidable.of(context);

    slidable?.openEndActionPane(
      duration: const Duration(milliseconds: 500),
      curve: Curves.decelerate,
    );

    Future.delayed(const Duration(seconds: 1), () {
      slidable?.close(
        duration: const Duration(milliseconds: 500),
        curve: Curves.bounceInOut,
      );
    });
  }

  @override
  Widget build(_) => const ListTile(title: Text('Slide me'));
}

lucasfcardozo avatar Feb 04 '22 02:02 lucasfcardozo

I would be a good feature indeed. We can do it by having a widget which launches an animation on initState and we would put this widget as the child of an ActionPane when needed. Someone want to try to make it and create a PR?

letsar avatar Jul 10 '22 14:07 letsar

@sarbogast Have you find a solution for it ?

Kiruel avatar Feb 22 '23 14:02 Kiruel

+1 for this option

wildsurfer avatar Jun 24 '23 13:06 wildsurfer