LCOV - code coverage report
Current view: top level - lib/PageHelpers - page_dragger.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 58 58 100.0 %
Date: 2021-03-10 21:05:26 Functions: 0 0 -

          Line data    Source code
       1             : import 'package:flutter/material.dart';
       2             : import 'package:liquid_swipe/Helpers/Helpers.dart';
       3             : import 'package:liquid_swipe/Helpers/slide_update.dart';
       4             : import 'package:liquid_swipe/Provider/LiquidProvider.dart';
       5             : import 'package:provider/provider.dart';
       6             : 
       7             : /// Internal Widget
       8             : ///
       9             : /// PageDragger is a Widget that handles user gestures and provide the data to the [LiquidProvider]
      10             : /// from where we perform animations various other methods.
      11             : class PageDragger extends StatefulWidget {
      12             :   /// Used to make animation faster or slower through it corresponding value
      13             :   /// default : [FULL_TRANSITION_PX]
      14             :   final double fullTransitionPX;
      15             : 
      16             :   /// Slide Icon whichever provided
      17             :   final Widget? slideIconWidget;
      18             : 
      19             :   /// double value should range from 0.0 - 1.0
      20             :   final double? iconPosition;
      21             : 
      22             :   /// boolean parameter to make user gesture disabled which LiquidSwipe is still Animating
      23             :   final bool ignoreUserGestureWhileAnimating;
      24             : 
      25             :   ///Constructor with some default values
      26           1 :   PageDragger({
      27             :     this.fullTransitionPX = FULL_TRANSITION_PX,
      28             :     this.slideIconWidget,
      29             :     this.iconPosition,
      30             :     this.ignoreUserGestureWhileAnimating = false,
      31             :   });
      32             : 
      33           1 :   @override
      34           1 :   _PageDraggerState createState() => _PageDraggerState();
      35             : }
      36             : 
      37             : ///State for PageDragger
      38             : class _PageDraggerState extends State<PageDragger> {
      39             :   GlobalKey _keyIcon = GlobalKey();
      40             : 
      41             :   ///Current [Offset] of the User Touch
      42             :   Offset? dragStart;
      43             : 
      44             :   ///Calculated Slide Direction of the Gesture/Swipe
      45             :   SlideDirection slideDirection = SlideDirection.none;
      46             : 
      47             :   ///Horizontally calculated slide percentage, ranges from 0.0 - 1.0
      48             :   double slidePercentHor = 0.0;
      49             : 
      50             :   ///Same as [slidePercentHor] but for Vertical Swipe and ranges from 0.0 - 1.25
      51             :   double slidePercentVer = 0.0;
      52             : 
      53             :   /// Method invoked when ever user touch the screen and drag starts
      54             :   /// called at [GestureDetector.onHorizontalDragStart]
      55           1 :   onDragStart(DragStartDetails details) {
      56           2 :     final model = Provider.of<LiquidProvider>(context, listen: false);
      57             : 
      58             :     ///Ignoring user gesture if the animation is running (optional)
      59           1 :     if (model.isAnimating && widget.ignoreUserGestureWhileAnimating ||
      60           1 :         model.isUserGestureDisabled) {
      61             :       return;
      62             :     }
      63           2 :     dragStart = details.globalPosition;
      64             :   }
      65             : 
      66             :   ///Updating data while user drags and touch offset changes
      67             :   ///called at [GestureDetector.onHorizontalDragUpdate]
      68           1 :   onDragUpdate(DragUpdateDetails details) {
      69           1 :     if (dragStart != null) {
      70             :       //Getting new position details
      71           1 :       final newPosition = details.globalPosition;
      72             :       //Change in position in x
      73           4 :       final dx = dragStart!.dx - newPosition.dx;
      74           1 :       final dy = newPosition.dy;
      75             : 
      76           1 :       slideDirection = SlideDirection.none;
      77             :       //predicting slide direction
      78           1 :       if (dx > 0.0) {
      79           1 :         slideDirection = SlideDirection.rightToLeft;
      80           1 :       } else if (dx < 0.0) {
      81           1 :         slideDirection = SlideDirection.leftToRight;
      82             :       }
      83             : 
      84             :       //predicting slide percent
      85           2 :       if (slideDirection != SlideDirection.none) {
      86             :         //clamp method is used to clamp the value of slidePercent from 0.0 to 1.0, after 1.0 it set to 1.0
      87           6 :         slidePercentHor = (dx / widget.fullTransitionPX).abs().clamp(0.0, 1.0);
      88           1 :         slidePercentVer =
      89           7 :             (dy / MediaQuery.of(context).size.height).abs().clamp(0.0, 1.0);
      90             :       }
      91             : 
      92           2 :       Provider.of<LiquidProvider>(context, listen: false)
      93           2 :           .updateSlide(SlideUpdate(
      94           1 :         slideDirection,
      95           1 :         slidePercentHor,
      96           1 :         slidePercentVer,
      97             :         UpdateType.dragging,
      98             :       ));
      99             :     }
     100             :   }
     101             : 
     102             :   ///This method executes when user ends dragging and leaves the screen
     103             :   ///called at [GestureDetector.onHorizontalDragEnd]
     104           1 :   onDragEnd(DragEndDetails details) {
     105           4 :     Provider.of<LiquidProvider>(context, listen: false).updateSlide(SlideUpdate(
     106             :       SlideDirection.none,
     107           1 :       slidePercentHor,
     108           1 :       slidePercentVer,
     109             :       UpdateType.doneDragging,
     110             :     ));
     111             : 
     112             :     //Making dragStart to null for the reallocation
     113           2 :     slidePercentHor = slidePercentVer = 0;
     114           1 :     slideDirection = SlideDirection.none;
     115           1 :     dragStart = null;
     116             :   }
     117             : 
     118           1 :   @override
     119             :   void initState() {
     120           1 :     super.initState();
     121           3 :     WidgetsBinding.instance!.addPostFrameCallback((_) {
     122           2 :       if (widget.slideIconWidget != null)
     123           2 :         Provider.of<LiquidProvider>(context, listen: false)
     124           4 :             .setIconSize(_keyIcon.currentContext!.size!);
     125             :     });
     126             :   }
     127             : 
     128           1 :   @override
     129             :   Widget build(BuildContext context) {
     130             :     //Gesture Detector for horizontal drag
     131           1 :     final model = Provider.of<LiquidProvider>(context, listen: false);
     132             : 
     133           1 :     return GestureDetector(
     134             :         behavior: HitTestBehavior.translucent,
     135           2 :         onHorizontalDragStart: model.isInProgress ? null : onDragStart,
     136           2 :         onHorizontalDragUpdate: model.isInProgress ? null : onDragUpdate,
     137           2 :         onHorizontalDragEnd: model.isInProgress ? null : onDragEnd,
     138           1 :         child: Align(
     139           1 :           alignment: Alignment(
     140           2 :             1 - slidePercentHor,
     141           6 :             -1.0 + Utils.handleIconAlignment(widget.iconPosition!) * 2,
     142             :           ),
     143           1 :           child: Opacity(
     144           2 :             opacity: 1 - slidePercentHor,
     145           2 :             child: slideDirection != SlideDirection.leftToRight &&
     146           2 :                     widget.slideIconWidget != null
     147           1 :                 ? SizedBox(
     148           1 :                     key: _keyIcon,
     149           1 :                     child: Padding(
     150             :                       padding: const EdgeInsets.symmetric(
     151             :                           horizontal: 2.0, vertical: 10.0),
     152           2 :                       child: widget.slideIconWidget,
     153             :                     ),
     154             :                   )
     155             :                 : null,
     156             :           ),
     157             :         ));
     158             :   }
     159             : }

Generated by: LCOV version 1.15