Search code examples
flutterdartflutter-animationflutter-widget

Flutter on tap Bounce fixed at one position when scrolled


I am working On Tap Bounce feature on my widget. I have referred to these links for information:

I got this package named as bouncing_widget, which was good enough for the workaround, but there is one limitation to it, i.e., It is not good for scrolling widget. You cannot scroll the page by tapping on the widget which uses this flutter bouncing widget

Somebody has already created a bug for the above widget, and no solution is found. Here is where you can find the issue: Bouncing Widget GitHub Issue

So, I decided to make my own widget which does the job for me. I have made the widget, and it works fine, but there is a limitation, i.e.,

When you scroll the page by holding on the widget, the widget stays there in one fixed position, that means, like it remains in pressed position

Here is my code:

import 'package:flutter/material.dart';

class CLBounceWidget extends StatefulWidget {
  final Function onPressed;
  final Widget child;

  CLBounceWidget({Key key, @required this.onPressed, @required this.child}): super(key:key);

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

class CLBounceWidgetState extends State<CLBounceWidget> with SingleTickerProviderStateMixin{
  double _scale;
  final Duration duration = Duration(milliseconds: 200);
  AnimationController _animationController;

  //Getting onPressed Calback
  VoidCallback get onPressed => widget.onPressed;

  @override
  void initState() {
    _animationController = AnimationController(
      vsync: this,
      duration: duration,
      lowerBound: 0.0,
      upperBound: 0.1
    )..addListener((){ setState((){}); });

    super.initState();
  }

  @override
  void dispose() {
    // TODO: implement dispose
    _animationController?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    _scale = 1 - _animationController.value;
    return GestureDetector(
      onTapDown: _onTapDown,
      onTapUp: _onTapUp,
      child: Transform.scale(
        scale: _scale,
        child: widget.child
      )
    );
  }

  // Triggering the onPressed callback with a check
  void _onTapTrigger(){
    if(onPressed != null){
      onPressed();
    }
  }

  //Start the animation
  _onTapDown(TapDownDetails details){
    _animationController.forward();
  }

  // We revise the animation and notify the user of the event
  _onTapUp(TapUpDetails details){
    Future.delayed(Duration(milliseconds: 100), (){
      _animationController.reverse();
    });

    //Finally calling the callback function
    _onTapTrigger();
  }
}

Also: I have tried doing this, without using Future, but with that, Animation only happens when long pressed, just _onTapTrigger() works:

_onTapUp(TapUpDetails details){
  _animationController.reverse();
  _onTapTrigger();
}

Tried: I have tried using onLongPress, onLongPressEnd, onLongPressMoveUpdate to at least do the _animationController.reverse();, but nothing worked out for me.

I want the widget to stay normal when I scroll the page while holding the widget, like a normal widget performs.


Solution

  • Since, after a long more researches, and hours and hours of toil, I finally found out what I was willing to have in my project. I have created a package on flutter pub.dev to help other developers in need of what the package flutter_bounce has to offer.

    You can search for flutter_bounce on the above link, or you can directly go to this: flutter_bounce

    To make use of it, you just need to do this:

    Bounce(
      duration: Duration(milliseconds: 110),
      onPressed: (){ YOUR_FUNCTION },
      child: YOUR_WIDGET
    )
    

    For more details, please feel free to read the README of the link. It has all necessary details. Happy coding :)