From 124225e272b02b77b59df6acd89a3b39b7aab3f2 Mon Sep 17 00:00:00 2001 From: NikhilVadoliya Date: Sat, 14 Nov 2020 09:58:05 +0530 Subject: [PATCH 1/4] Code Refactor Deprecated parameter : sliderMenuOpenOffset and sliderMenuCloseOffset . You can use sliderMenuOpenSize and sliderMenuCloseOffset Deprecated SliderOpen . You can use SlideDirection. Remove AnimationContainer and used AnimationBuilder Deprecated sliderAnimationTimeInMilliseconds. You can use animationDuration --- example/lib/main.dart | 5 +- lib/src/slider.dart | 204 ++++++++++++++++++++++----------------- lib/src/slider_open.dart | 2 +- 3 files changed, 118 insertions(+), 93 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 4fb85ab..be32ffd 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -34,8 +34,11 @@ class _MyAppState extends State { appBarColor: Colors.white, key: _key, appBarPadding: const EdgeInsets.only(top: 20), - sliderMenuOpenOffset: 250, + sliderMenuOpenSize: 200, + sliderMenuCloseSize: 60, + // slideDirection: SlideDirection.TOP_TO_BOTTOM, appBarHeight: 60, + // isShadow: true, title: Text( title, style: TextStyle(fontSize: 22, fontWeight: FontWeight.w700), diff --git a/lib/src/slider.dart b/lib/src/slider.dart index bd73e21..f553e74 100644 --- a/lib/src/slider.dart +++ b/lib/src/slider.dart @@ -1,12 +1,13 @@ +import 'package:flutter/animation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_slider_drawer/flutter_slider_drawer.dart'; class SliderMenuContainer extends StatefulWidget { final Widget sliderMenu; final Widget sliderMain; - final int sliderAnimationTimeInMilliseconds; - final double sliderMenuOpenOffset; - final double sliderMenuCloseOffset; + final int animationDuration; + final double sliderMenuOpenSize; + final double sliderMenuCloseSize; final Color drawerIconColor; final Widget drawerIcon; @@ -23,14 +24,14 @@ class SliderMenuContainer extends StatefulWidget { final Widget trailing; final Color appBarColor; final EdgeInsets appBarPadding; - final SliderOpen sliderOpen; + final SlideDirection slideDirection; const SliderMenuContainer({ Key key, this.sliderMenu, this.sliderMain, - this.sliderAnimationTimeInMilliseconds = 200, - this.sliderMenuOpenOffset = 265, + this.animationDuration = 200, + this.sliderMenuOpenSize = 265, this.drawerIconColor = Colors.black, this.drawerIcon, this.splashColor, @@ -41,8 +42,8 @@ class SliderMenuContainer extends StatefulWidget { this.title, this.drawerIconSize = 27, this.appBarHeight, - this.sliderMenuCloseOffset = 0, - this.sliderOpen = SliderOpen.LEFT_TO_RIGHT, + this.sliderMenuCloseSize = 0, + this.slideDirection = SlideDirection.LEFT_TO_RIGHT, this.isShadow = false, this.shadowColor = Colors.grey, this.shadowBlurRadius = 25.0, @@ -56,23 +57,29 @@ class SliderMenuContainer extends StatefulWidget { } class SliderMenuContainerState extends State - with SingleTickerProviderStateMixin { + with TickerProviderStateMixin { double _slideBarXOffset = 0; double _slideBarYOffset = 0; bool _isSlideBarOpen = false; - AnimationController _animationController; + + // AnimationController _animationButtonController; + AnimationController _animationDrawerController; + Animation animation; Widget drawerIcon; /// check whether drawer is open - bool get isDrawerOpen => _isSlideBarOpen; + bool get isDrawerOpen => _animationDrawerController.isCompleted; /// Toggle drawer void toggle() { - setState(() { + _animationDrawerController.isCompleted + ? _animationDrawerController.reverse() + : _animationDrawerController.forward(); + /*setState(() { _isSlideBarOpen - ? _animationController.reverse() - : _animationController.forward(); + ? _animationButtonController.reverse() + : _animationButtonController.forward(); if (widget.sliderOpen == SliderOpen.LEFT_TO_RIGHT || widget.sliderOpen == SliderOpen.RIGHT_TO_LEFT) { _slideBarXOffset = _isSlideBarOpen @@ -85,13 +92,14 @@ class SliderMenuContainerState extends State } _isSlideBarOpen = !_isSlideBarOpen; - }); + });*/ } /// Open drawer void openDrawer() { - setState(() { - _animationController.forward(); + _animationDrawerController.forward(); + /*setState(() { + _animationButtonController.forward(); if (widget.sliderOpen == SliderOpen.LEFT_TO_RIGHT || widget.sliderOpen == SliderOpen.RIGHT_TO_LEFT) { _slideBarXOffset = widget.sliderMenuOpenOffset; @@ -99,13 +107,14 @@ class SliderMenuContainerState extends State _slideBarYOffset = widget.sliderMenuOpenOffset; } _isSlideBarOpen = true; - }); + });*/ } /// Close drawer void closeDrawer() { - setState(() { - _animationController.reverse(); + _animationDrawerController.reverse(); + /* setState(() { + _animationButtonController.reverse(); if (widget.sliderOpen == SliderOpen.LEFT_TO_RIGHT || widget.sliderOpen == SliderOpen.RIGHT_TO_LEFT) { _slideBarXOffset = widget.sliderMenuCloseOffset; @@ -113,17 +122,27 @@ class SliderMenuContainerState extends State _slideBarYOffset = widget.sliderMenuCloseOffset; } _isSlideBarOpen = false; - }); + });*/ } @override void initState() { super.initState(); - - _animationController = AnimationController( + /* _animationButtonController = AnimationController( vsync: this, duration: - Duration(milliseconds: widget.sliderAnimationTimeInMilliseconds)); + Duration(milliseconds: widget.sliderAnimationTimeInMilliseconds));*/ + + _animationDrawerController = AnimationController( + vsync: this, + duration: Duration(milliseconds: widget.animationDuration)); + + animation = Tween( + begin: widget.sliderMenuCloseSize, end: widget.sliderMenuOpenSize) + .animate(CurvedAnimation( + parent: _animationDrawerController, + curve: Curves.easeIn, + reverseCurve: Curves.easeOut)); } @override @@ -133,38 +152,49 @@ class SliderMenuContainerState extends State /// Display Menu menuWidget(), - /// Displaying the shadow + /// Dev -Displaying the shadow if (widget.isShadow) ...[ - AnimatedContainer( - duration: - Duration(milliseconds: widget.sliderAnimationTimeInMilliseconds), - curve: Curves.easeIn, - width: double.infinity, - height: double.infinity, - transform: getTranslationValuesForShadow(widget.sliderOpen), - decoration: BoxDecoration(shape: BoxShape.rectangle, boxShadow: [ - BoxShadow( - color: widget.shadowColor, - blurRadius: widget.shadowBlurRadius, // soften the shadow - spreadRadius: widget.shadowSpreadRadius, //extend the shadow - offset: Offset( - 15.0, // Move to right 10 horizontally - 15.0, // Move to bottom 10 Vertically - ), - ) - ]), + AnimatedBuilder( + animation: _animationDrawerController, + builder: (anim, child) { + return Transform.translate( + offset: getOffsetValueForShadow( + widget.slideDirection, animation.value), + child: child, + ); + return child; + }, + child: Container( + width: double.infinity, + height: double.infinity, + decoration: BoxDecoration(shape: BoxShape.rectangle, boxShadow: [ + BoxShadow( + color: widget.shadowColor, + blurRadius: widget.shadowBlurRadius, // soften the shadow + spreadRadius: widget.shadowSpreadRadius, //extend the shadow + offset: Offset( + 15.0, // Move to right 10 horizontally + 15.0, // Move to bottom 10 Vertically + ), + ) + ]), + ), ), ], - /// Display Main Screen - AnimatedContainer( - duration: - Duration(milliseconds: widget.sliderAnimationTimeInMilliseconds), - curve: Curves.easeIn, + //Dev- Display Main Screen + AnimatedBuilder( + animation: _animationDrawerController, + builder: (anim, child) { + return Transform.translate( + offset: getOffsetValues(widget.slideDirection, animation.value), + child: child, + ); + }, + child: Container( width: double.infinity, height: double.infinity, - color: widget.appBarColor, - transform: getTranslationValues(widget.sliderOpen), + color: widget.appBarColor, child: Column( children: [ Container( @@ -176,7 +206,9 @@ class SliderMenuContainerState extends State ), Expanded(child: widget.sliderMain), ], - )), + ), + ), + ), ])); } @@ -189,10 +221,8 @@ class SliderMenuContainerState extends State icon: AnimatedIcons.menu_close, color: widget.drawerIconColor, size: widget.drawerIconSize, - progress: _animationController), - onPressed: () { - toggle(); - }), + progress: _animationDrawerController), + onPressed: () => toggle()), Expanded( child: widget.isTitleCenter ? Center( @@ -206,7 +236,7 @@ class SliderMenuContainerState extends State ) ]; - if (widget.sliderOpen == SliderOpen.RIGHT_TO_LEFT) { + if (widget.slideDirection == SlideDirection.RIGHT_TO_LEFT) { return list.reversed.toList(); } return list; @@ -214,30 +244,30 @@ class SliderMenuContainerState extends State /// Build and Align the Menu widget based on the slide open type menuWidget() { - switch (widget.sliderOpen) { - case SliderOpen.LEFT_TO_RIGHT: + switch (widget.slideDirection) { + case SlideDirection.LEFT_TO_RIGHT: return Container( - width: widget.sliderMenuOpenOffset, + width: widget.sliderMenuOpenSize, child: widget.sliderMenu, ); break; - case SliderOpen.RIGHT_TO_LEFT: + case SlideDirection.RIGHT_TO_LEFT: return Positioned( right: 0, top: 0, bottom: 0, child: Container( - width: widget.sliderMenuOpenOffset, + width: widget.sliderMenuOpenSize, child: widget.sliderMenu, ), ); - case SliderOpen.TOP_TO_BOTTOM: + case SlideDirection.TOP_TO_BOTTOM: return Positioned( right: 0, left: 0, top: 0, child: Container( - width: widget.sliderMenuOpenOffset, + width: widget.sliderMenuOpenSize, child: widget.sliderMenu, ), ); @@ -246,46 +276,38 @@ class SliderMenuContainerState extends State } /// - /// This method get Matrix4 data base on [sliderOpen] type + /// This method get Offset base on [sliderOpen] type /// - Matrix4 getTranslationValues(SliderOpen sliderOpen) { - switch (sliderOpen) { - case SliderOpen.LEFT_TO_RIGHT: - return Matrix4.translationValues( - _slideBarXOffset, _slideBarYOffset, 1.0); - case SliderOpen.RIGHT_TO_LEFT: - return Matrix4.translationValues( - -_slideBarXOffset, _slideBarYOffset, 1.0); - - case SliderOpen.TOP_TO_BOTTOM: - return Matrix4.translationValues(0, _slideBarYOffset, 1.0); - + Offset getOffsetValues(SlideDirection direction, double value) { + switch (direction) { + case SlideDirection.LEFT_TO_RIGHT: + return Offset(value, 0); + case SlideDirection.RIGHT_TO_LEFT: + return Offset(-value, 0); + case SlideDirection.TOP_TO_BOTTOM: + return Offset(0, value); default: - return Matrix4.translationValues(0, 0, 1.0); + return Offset(value, 0); } } - Matrix4 getTranslationValuesForShadow(SliderOpen sliderOpen) { - switch (sliderOpen) { - case SliderOpen.LEFT_TO_RIGHT: - return Matrix4.translationValues( - _slideBarXOffset - 30, _slideBarYOffset, 1.0); - case SliderOpen.RIGHT_TO_LEFT: - return Matrix4.translationValues( - -_slideBarXOffset - 5, _slideBarYOffset, 1.0); - - case SliderOpen.TOP_TO_BOTTOM: - return Matrix4.translationValues(0, _slideBarYOffset - 20, 1.0); - + Offset getOffsetValueForShadow(SlideDirection direction, double value) { + switch (direction) { + case SlideDirection.LEFT_TO_RIGHT: + return Offset(value - (widget.sliderMenuOpenSize > 50 ? 20 : 10), 0); + case SlideDirection.RIGHT_TO_LEFT: + return Offset(-value - 5, 0); + case SlideDirection.TOP_TO_BOTTOM: + return Offset(0, value - (widget.sliderMenuOpenSize > 50 ? 15 : 5)); default: - return Matrix4.translationValues(0, 0, 1.0); + return Offset(value - 30.0, 0); } } @override void dispose() { super.dispose(); - _animationController.dispose(); + _animationDrawerController.dispose(); } } diff --git a/lib/src/slider_open.dart b/lib/src/slider_open.dart index 9fa7f9f..7d5d1b3 100644 --- a/lib/src/slider_open.dart +++ b/lib/src/slider_open.dart @@ -1 +1 @@ -enum SliderOpen { LEFT_TO_RIGHT, RIGHT_TO_LEFT, TOP_TO_BOTTOM } +enum SlideDirection { LEFT_TO_RIGHT, RIGHT_TO_LEFT, TOP_TO_BOTTOM } From e984f7eba58e876811247ff6bad9415d1ab473e3 Mon Sep 17 00:00:00 2001 From: NikhilVadoliya Date: Sat, 14 Nov 2020 10:07:14 +0530 Subject: [PATCH 2/4] :sparkles: - provide animationController --- example/lib/main.dart | 4 +--- lib/src/slider.dart | 56 ++++--------------------------------------- 2 files changed, 5 insertions(+), 55 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index be32ffd..d8dc35b 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -16,7 +16,7 @@ class MyApp extends StatefulWidget { class _MyAppState extends State { GlobalKey _key = - new GlobalKey(); + new GlobalKey(); String title; @override @@ -36,9 +36,7 @@ class _MyAppState extends State { appBarPadding: const EdgeInsets.only(top: 20), sliderMenuOpenSize: 200, sliderMenuCloseSize: 60, - // slideDirection: SlideDirection.TOP_TO_BOTTOM, appBarHeight: 60, - // isShadow: true, title: Text( title, style: TextStyle(fontSize: 22, fontWeight: FontWeight.w700), diff --git a/lib/src/slider.dart b/lib/src/slider.dart index f553e74..09a2246 100644 --- a/lib/src/slider.dart +++ b/lib/src/slider.dart @@ -58,11 +58,6 @@ class SliderMenuContainer extends StatefulWidget { class SliderMenuContainerState extends State with TickerProviderStateMixin { - double _slideBarXOffset = 0; - double _slideBarYOffset = 0; - bool _isSlideBarOpen = false; - - // AnimationController _animationButtonController; AnimationController _animationDrawerController; Animation animation; @@ -71,67 +66,24 @@ class SliderMenuContainerState extends State /// check whether drawer is open bool get isDrawerOpen => _animationDrawerController.isCompleted; + AnimationController get animationController => _animationDrawerController; + /// Toggle drawer void toggle() { _animationDrawerController.isCompleted ? _animationDrawerController.reverse() : _animationDrawerController.forward(); - /*setState(() { - _isSlideBarOpen - ? _animationButtonController.reverse() - : _animationButtonController.forward(); - if (widget.sliderOpen == SliderOpen.LEFT_TO_RIGHT || - widget.sliderOpen == SliderOpen.RIGHT_TO_LEFT) { - _slideBarXOffset = _isSlideBarOpen - ? widget.sliderMenuCloseOffset - : widget.sliderMenuOpenOffset; - } else { - _slideBarYOffset = _isSlideBarOpen - ? widget.sliderMenuCloseOffset - : widget.sliderMenuOpenOffset; - } - - _isSlideBarOpen = !_isSlideBarOpen; - });*/ } /// Open drawer - void openDrawer() { - _animationDrawerController.forward(); - /*setState(() { - _animationButtonController.forward(); - if (widget.sliderOpen == SliderOpen.LEFT_TO_RIGHT || - widget.sliderOpen == SliderOpen.RIGHT_TO_LEFT) { - _slideBarXOffset = widget.sliderMenuOpenOffset; - } else { - _slideBarYOffset = widget.sliderMenuOpenOffset; - } - _isSlideBarOpen = true; - });*/ - } + void openDrawer() => _animationDrawerController.forward(); /// Close drawer - void closeDrawer() { - _animationDrawerController.reverse(); - /* setState(() { - _animationButtonController.reverse(); - if (widget.sliderOpen == SliderOpen.LEFT_TO_RIGHT || - widget.sliderOpen == SliderOpen.RIGHT_TO_LEFT) { - _slideBarXOffset = widget.sliderMenuCloseOffset; - } else { - _slideBarYOffset = widget.sliderMenuCloseOffset; - } - _isSlideBarOpen = false; - });*/ - } + void closeDrawer() => _animationDrawerController.reverse(); @override void initState() { super.initState(); - /* _animationButtonController = AnimationController( - vsync: this, - duration: - Duration(milliseconds: widget.sliderAnimationTimeInMilliseconds));*/ _animationDrawerController = AnimationController( vsync: this, From bc279be86f40cdbea9df7598ea4e0920c8e5d744 Mon Sep 17 00:00:00 2001 From: NikhilVadoliya Date: Sat, 14 Nov 2020 14:19:30 +0530 Subject: [PATCH 3/4] :recycle: code refactor --- lib/flutter_slider_drawer.dart | 2 +- lib/src/app_bar.dart | 76 +++++++++ lib/src/helper/utils.dart | 36 +++++ lib/src/menu_bar.dart | 34 ++++ lib/src/slider.dart | 153 +++++------------- ...slider_open.dart => slider_direction.dart} | 0 6 files changed, 186 insertions(+), 115 deletions(-) create mode 100644 lib/src/app_bar.dart create mode 100644 lib/src/helper/utils.dart create mode 100644 lib/src/menu_bar.dart rename lib/src/{slider_open.dart => slider_direction.dart} (100%) diff --git a/lib/flutter_slider_drawer.dart b/lib/flutter_slider_drawer.dart index 2da0bcd..4d65686 100644 --- a/lib/flutter_slider_drawer.dart +++ b/lib/flutter_slider_drawer.dart @@ -1,4 +1,4 @@ library flutter_slider_drawer; -export 'package:flutter_slider_drawer/src/slider_open.dart'; +export 'package:flutter_slider_drawer/src/slider_direction.dart'; export 'package:flutter_slider_drawer/src/slider.dart'; diff --git a/lib/src/app_bar.dart b/lib/src/app_bar.dart new file mode 100644 index 0000000..f1868d5 --- /dev/null +++ b/lib/src/app_bar.dart @@ -0,0 +1,76 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_slider_drawer/src/slider_direction.dart'; + +class SliderAppBar extends StatelessWidget { + final EdgeInsets appBarPadding; + final Color appBarColor; + final Widget drawerIcon; + final Color splashColor; + final Color drawerIconColor; + final double drawerIconSize; + final double appBarHeight; + final AnimationController animationController; + final VoidCallback onTap; + final Widget title; + final bool isTitleCenter; + final Widget trailing; + final SlideDirection slideDirection; + + const SliderAppBar( + {Key key, + this.appBarPadding, + this.appBarColor, + this.drawerIcon, + this.splashColor, + this.drawerIconColor, + this.drawerIconSize, + this.animationController, + this.onTap, + this.title, + this.isTitleCenter, + this.trailing, + this.slideDirection, this.appBarHeight}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + height: appBarHeight, + padding: appBarPadding ?? const EdgeInsets.only(top: 24), + color: appBarColor, + child: Row( + children: appBar(), + ), + ); + } + + List appBar() { + List list = [ + drawerIcon ?? + IconButton( + splashColor: splashColor ?? Colors.black, + icon: AnimatedIcon( + icon: AnimatedIcons.menu_close, + color: drawerIconColor, + size: drawerIconSize, + progress: animationController), + onPressed: () => onTap()), + Expanded( + child: isTitleCenter + ? Center( + child: title, + ) + : title, + ), + trailing ?? + SizedBox( + width: 35, + ) + ]; + + if (slideDirection == SlideDirection.RIGHT_TO_LEFT) { + return list.reversed.toList(); + } + return list; + } +} diff --git a/lib/src/helper/utils.dart b/lib/src/helper/utils.dart new file mode 100644 index 0000000..75de548 --- /dev/null +++ b/lib/src/helper/utils.dart @@ -0,0 +1,36 @@ +import 'dart:ui'; + +import 'package:flutter_slider_drawer/flutter_slider_drawer.dart'; + +class Utils { + /// + /// This method get Offset base on [sliderOpen] type + /// + + static Offset getOffsetValues(SlideDirection direction, double value) { + switch (direction) { + case SlideDirection.LEFT_TO_RIGHT: + return Offset(value, 0); + case SlideDirection.RIGHT_TO_LEFT: + return Offset(-value, 0); + case SlideDirection.TOP_TO_BOTTOM: + return Offset(0, value); + default: + return Offset(value, 0); + } + } + + static Offset getOffsetValueForShadow( + SlideDirection direction, double value, double slideOpenWidth) { + switch (direction) { + case SlideDirection.LEFT_TO_RIGHT: + return Offset(value - (slideOpenWidth > 50 ? 20 : 10), 0); + case SlideDirection.RIGHT_TO_LEFT: + return Offset(-value - 5, 0); + case SlideDirection.TOP_TO_BOTTOM: + return Offset(0, value - (slideOpenWidth > 50 ? 15 : 5)); + default: + return Offset(value - 30.0, 0); + } + } +} diff --git a/lib/src/menu_bar.dart b/lib/src/menu_bar.dart new file mode 100644 index 0000000..744e45f --- /dev/null +++ b/lib/src/menu_bar.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_slider_drawer/src/slider_direction.dart'; + +/// +/// Build and Align the Menu widget based on the slide open type +/// +class SlideMenuBar extends StatelessWidget { + final SlideDirection slideDirection; + final double sliderMenuOpenSize; + final Widget sliderMenu; + + const SlideMenuBar( + {Key key, this.slideDirection, this.sliderMenuOpenSize, this.sliderMenu}) + : super(key: key); + + @override + Widget build(BuildContext context) { + var container = Container( + width: sliderMenuOpenSize, + child: sliderMenu, + ); + switch (slideDirection) { + case SlideDirection.LEFT_TO_RIGHT: + return container; + break; + case SlideDirection.RIGHT_TO_LEFT: + return Positioned(right: 0, top: 0, bottom: 0, child: container); + case SlideDirection.TOP_TO_BOTTOM: + return Positioned(right: 0, left: 0, top: 0, child: container); + break; + } + return Container(); + } +} diff --git a/lib/src/slider.dart b/lib/src/slider.dart index 09a2246..4eddef0 100644 --- a/lib/src/slider.dart +++ b/lib/src/slider.dart @@ -1,6 +1,9 @@ import 'package:flutter/animation.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_slider_drawer/flutter_slider_drawer.dart'; +import 'package:flutter_slider_drawer/src/app_bar.dart'; +import 'package:flutter_slider_drawer/src/menu_bar.dart'; +import 'package:flutter_slider_drawer/src/helper/utils.dart'; +import 'package:flutter_slider_drawer/src/slider_direction.dart'; class SliderMenuContainer extends StatefulWidget { final Widget sliderMenu; @@ -9,6 +12,7 @@ class SliderMenuContainer extends StatefulWidget { final double sliderMenuOpenSize; final double sliderMenuCloseSize; + final bool hasAppBar; final Color drawerIconColor; final Widget drawerIcon; final double drawerIconSize; @@ -41,13 +45,14 @@ class SliderMenuContainer extends StatefulWidget { this.appBarPadding, this.title, this.drawerIconSize = 27, - this.appBarHeight, + this.appBarHeight = 70, this.sliderMenuCloseSize = 0, this.slideDirection = SlideDirection.LEFT_TO_RIGHT, this.isShadow = false, this.shadowColor = Colors.grey, this.shadowBlurRadius = 25.0, this.shadowSpreadRadius = 5.0, + this.hasAppBar = true, }) : assert(sliderMenu != null), assert(sliderMain != null), super(key: key); @@ -66,14 +71,13 @@ class SliderMenuContainerState extends State /// check whether drawer is open bool get isDrawerOpen => _animationDrawerController.isCompleted; + /// it's provide [animationController] for handle and lister drawer animation AnimationController get animationController => _animationDrawerController; /// Toggle drawer - void toggle() { - _animationDrawerController.isCompleted - ? _animationDrawerController.reverse() - : _animationDrawerController.forward(); - } + void toggle() => _animationDrawerController.isCompleted + ? _animationDrawerController.reverse() + : _animationDrawerController.forward(); /// Open drawer void openDrawer() => _animationDrawerController.forward(); @@ -102,16 +106,20 @@ class SliderMenuContainerState extends State return Container( child: Stack(children: [ /// Display Menu - menuWidget(), + SlideMenuBar( + slideDirection: widget.slideDirection, + sliderMenu: widget.sliderMenu, + sliderMenuOpenSize: widget.sliderMenuOpenSize, + ), - /// Dev -Displaying the shadow + /// Displaying the shadow if (widget.isShadow) ...[ AnimatedBuilder( animation: _animationDrawerController, builder: (anim, child) { return Transform.translate( - offset: getOffsetValueForShadow( - widget.slideDirection, animation.value), + offset: Utils.getOffsetValueForShadow(widget.slideDirection, + animation.value, widget.sliderMenuOpenSize), child: child, ); return child; @@ -125,8 +133,8 @@ class SliderMenuContainerState extends State blurRadius: widget.shadowBlurRadius, // soften the shadow spreadRadius: widget.shadowSpreadRadius, //extend the shadow offset: Offset( - 15.0, // Move to right 10 horizontally - 15.0, // Move to bottom 10 Vertically + 15.0, // Move to right 15 horizontally + 15.0, // Move to bottom 15 Vertically ), ) ]), @@ -134,12 +142,13 @@ class SliderMenuContainerState extends State ), ], - //Dev- Display Main Screen + //Display Main Screen AnimatedBuilder( animation: _animationDrawerController, builder: (anim, child) { return Transform.translate( - offset: getOffsetValues(widget.slideDirection, animation.value), + offset: + Utils.getOffsetValues(widget.slideDirection, animation.value), child: child, ); }, @@ -149,13 +158,22 @@ class SliderMenuContainerState extends State color: widget.appBarColor, child: Column( children: [ - Container( - padding: widget.appBarPadding ?? const EdgeInsets.only(top: 24), - color: widget.appBarColor, - child: Row( - children: appBar(), + if (widget.hasAppBar) + SliderAppBar( + slideDirection: widget.slideDirection, + onTap: () => toggle(), + appBarHeight: widget.appBarHeight, + animationController: _animationDrawerController, + appBarColor: widget.appBarColor, + appBarPadding: widget.appBarPadding, + drawerIcon: widget.drawerIcon, + drawerIconColor: widget.drawerIconColor, + drawerIconSize: widget.drawerIconSize, + isTitleCenter: widget.isTitleCenter, + splashColor: widget.splashColor, + title: widget.title ?? '', + trailing: widget.trailing, ), - ), Expanded(child: widget.sliderMain), ], ), @@ -164,99 +182,6 @@ class SliderMenuContainerState extends State ])); } - List appBar() { - List list = [ - widget.drawerIcon ?? - IconButton( - splashColor: widget.splashColor ?? Colors.black, - icon: AnimatedIcon( - icon: AnimatedIcons.menu_close, - color: widget.drawerIconColor, - size: widget.drawerIconSize, - progress: _animationDrawerController), - onPressed: () => toggle()), - Expanded( - child: widget.isTitleCenter - ? Center( - child: widget.title, - ) - : widget.title, - ), - widget.trailing ?? - SizedBox( - width: 35, - ) - ]; - - if (widget.slideDirection == SlideDirection.RIGHT_TO_LEFT) { - return list.reversed.toList(); - } - return list; - } - - /// Build and Align the Menu widget based on the slide open type - menuWidget() { - switch (widget.slideDirection) { - case SlideDirection.LEFT_TO_RIGHT: - return Container( - width: widget.sliderMenuOpenSize, - child: widget.sliderMenu, - ); - break; - case SlideDirection.RIGHT_TO_LEFT: - return Positioned( - right: 0, - top: 0, - bottom: 0, - child: Container( - width: widget.sliderMenuOpenSize, - child: widget.sliderMenu, - ), - ); - case SlideDirection.TOP_TO_BOTTOM: - return Positioned( - right: 0, - left: 0, - top: 0, - child: Container( - width: widget.sliderMenuOpenSize, - child: widget.sliderMenu, - ), - ); - break; - } - } - - /// - /// This method get Offset base on [sliderOpen] type - /// - - Offset getOffsetValues(SlideDirection direction, double value) { - switch (direction) { - case SlideDirection.LEFT_TO_RIGHT: - return Offset(value, 0); - case SlideDirection.RIGHT_TO_LEFT: - return Offset(-value, 0); - case SlideDirection.TOP_TO_BOTTOM: - return Offset(0, value); - default: - return Offset(value, 0); - } - } - - Offset getOffsetValueForShadow(SlideDirection direction, double value) { - switch (direction) { - case SlideDirection.LEFT_TO_RIGHT: - return Offset(value - (widget.sliderMenuOpenSize > 50 ? 20 : 10), 0); - case SlideDirection.RIGHT_TO_LEFT: - return Offset(-value - 5, 0); - case SlideDirection.TOP_TO_BOTTOM: - return Offset(0, value - (widget.sliderMenuOpenSize > 50 ? 15 : 5)); - default: - return Offset(value - 30.0, 0); - } - } - @override void dispose() { super.dispose(); diff --git a/lib/src/slider_open.dart b/lib/src/slider_direction.dart similarity index 100% rename from lib/src/slider_open.dart rename to lib/src/slider_direction.dart From d44608ffa17b088e6f3a600f2f38a2854dc5196f Mon Sep 17 00:00:00 2001 From: Nikhil Vadoliya Date: Sat, 28 Nov 2020 16:18:32 +0530 Subject: [PATCH 4/4] implement swipe gesture in left and right drawer --- example/lib/main.dart | 42 +++--- example/lib/main_widget.dart | 5 +- lib/src/slider.dart | 243 +++++++++++++++++++++++++---------- 3 files changed, 199 insertions(+), 91 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index d8dc35b..362a4c1 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -16,7 +16,7 @@ class MyApp extends StatefulWidget { class _MyAppState extends State { GlobalKey _key = - new GlobalKey(); + new GlobalKey(); String title; @override @@ -30,26 +30,26 @@ class _MyAppState extends State { return MaterialApp( debugShowCheckedModeBanner: false, home: Scaffold( - body: SliderMenuContainer( - appBarColor: Colors.white, - key: _key, - appBarPadding: const EdgeInsets.only(top: 20), - sliderMenuOpenSize: 200, - sliderMenuCloseSize: 60, - appBarHeight: 60, - title: Text( - title, - style: TextStyle(fontSize: 22, fontWeight: FontWeight.w700), - ), - sliderMenu: MenuWidget( - onItemClick: (title) { - _key.currentState.closeDrawer(); - setState(() { - this.title = title; - }); - }, - ), - sliderMain: MainWidget()), + body: Padding( + padding: const EdgeInsets.only(top: 0), + child: SliderMenuContainer( + appBarColor: Colors.white, + key: _key, + sliderMenuOpenSize: 200, + title: Text( + title, + style: TextStyle(fontSize: 22, fontWeight: FontWeight.w700), + ), + sliderMenu: MenuWidget( + onItemClick: (title) { + _key.currentState.closeDrawer(); + setState(() { + this.title = title; + }); + }, + ), + sliderMain: MainWidget()), + ), ), ); } diff --git a/example/lib/main_widget.dart b/example/lib/main_widget.dart index 62c4d92..b51c5ff 100644 --- a/example/lib/main_widget.dart +++ b/example/lib/main_widget.dart @@ -27,8 +27,11 @@ class _MainWidgetState extends State { @override Widget build(BuildContext context) { return Container( + margin: const EdgeInsets.all(20), child: ListView.separated( - padding: const EdgeInsets.symmetric(horizontal: 10), + scrollDirection: Axis.vertical, + // physics: BouncingScrollPhysics(), + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), itemBuilder: (builder, index) { return LimitedBox( maxHeight: 150, diff --git a/lib/src/slider.dart b/lib/src/slider.dart index 4eddef0..900e51f 100644 --- a/lib/src/slider.dart +++ b/lib/src/slider.dart @@ -11,6 +11,7 @@ class SliderMenuContainer extends StatefulWidget { final int animationDuration; final double sliderMenuOpenSize; final double sliderMenuCloseSize; + final bool isDraggable; final bool hasAppBar; final Color drawerIconColor; @@ -34,6 +35,7 @@ class SliderMenuContainer extends StatefulWidget { Key key, this.sliderMenu, this.sliderMain, + this.isDraggable = true, this.animationDuration = 200, this.sliderMenuOpenSize = 265, this.drawerIconColor = Colors.black, @@ -63,9 +65,17 @@ class SliderMenuContainer extends StatefulWidget { class SliderMenuContainerState extends State with TickerProviderStateMixin { + static const double WIDTH_GESTURE = 50.0; + static const double HEIGHT_GESTURE = 30.0; + static const double BLUR_SHADOW = 20.0; + double slideAmount = 0.0; + double _percent = 0.0; + AnimationController _animationDrawerController; Animation animation; + bool dragging = false; + Widget drawerIcon; /// check whether drawer is open @@ -103,83 +113,94 @@ class SliderMenuContainerState extends State @override Widget build(BuildContext context) { - return Container( - child: Stack(children: [ - /// Display Menu - SlideMenuBar( - slideDirection: widget.slideDirection, - sliderMenu: widget.sliderMenu, - sliderMenuOpenSize: widget.sliderMenuOpenSize, - ), - - /// Displaying the shadow - if (widget.isShadow) ...[ + return LayoutBuilder(builder: (context, constrain) { + return Container( + child: Stack(children: [ + /// Display Menu + SlideMenuBar( + slideDirection: widget.slideDirection, + sliderMenu: widget.sliderMenu, + sliderMenuOpenSize: widget.sliderMenuOpenSize, + ), + + /// Displaying the shadow + if (widget.isShadow) ...[ + AnimatedBuilder( + animation: _animationDrawerController, + builder: (_, child) { + return Transform.translate( + offset: Utils.getOffsetValueForShadow(widget.slideDirection, + animation.value, widget.sliderMenuOpenSize), + child: child, + ); + return child; + }, + child: Container( + width: double.infinity, + height: double.infinity, + decoration: BoxDecoration(shape: BoxShape.rectangle, boxShadow: [ + BoxShadow( + color: widget.shadowColor, + blurRadius: widget.shadowBlurRadius, + // soften the shadow + spreadRadius: widget.shadowSpreadRadius, + //extend the shadow + offset: Offset( + 15.0, // Move to right 15 horizontally + 15.0, // Move to bottom 15 Vertically + ), + ) + ]), + ), + ), + ], + + //Display Main Screen AnimatedBuilder( animation: _animationDrawerController, - builder: (anim, child) { + builder: (_, child) { return Transform.translate( - offset: Utils.getOffsetValueForShadow(widget.slideDirection, - animation.value, widget.sliderMenuOpenSize), + offset: + Utils.getOffsetValues(widget.slideDirection, animation.value), child: child, ); - return child; }, - child: Container( - width: double.infinity, - height: double.infinity, - decoration: BoxDecoration(shape: BoxShape.rectangle, boxShadow: [ - BoxShadow( - color: widget.shadowColor, - blurRadius: widget.shadowBlurRadius, // soften the shadow - spreadRadius: widget.shadowSpreadRadius, //extend the shadow - offset: Offset( - 15.0, // Move to right 15 horizontally - 15.0, // Move to bottom 15 Vertically - ), - ) - ]), - ), - ), - ], - - //Display Main Screen - AnimatedBuilder( - animation: _animationDrawerController, - builder: (anim, child) { - return Transform.translate( - offset: - Utils.getOffsetValues(widget.slideDirection, animation.value), - child: child, - ); - }, - child: Container( - width: double.infinity, - height: double.infinity, - color: widget.appBarColor, - child: Column( - children: [ - if (widget.hasAppBar) - SliderAppBar( - slideDirection: widget.slideDirection, - onTap: () => toggle(), - appBarHeight: widget.appBarHeight, - animationController: _animationDrawerController, - appBarColor: widget.appBarColor, - appBarPadding: widget.appBarPadding, - drawerIcon: widget.drawerIcon, - drawerIconColor: widget.drawerIconColor, - drawerIconSize: widget.drawerIconSize, - isTitleCenter: widget.isTitleCenter, - splashColor: widget.splashColor, - title: widget.title ?? '', - trailing: widget.trailing, - ), - Expanded(child: widget.sliderMain), - ], + child: GestureDetector( + behavior: HitTestBehavior.deferToChild, + onHorizontalDragStart: _onHorizontalDragStart, + onHorizontalDragEnd: _onHorizontalDragEnd, + onHorizontalDragUpdate: (detail) => + _onHorizontalDragUpdate(detail, constrain), + child: Container( + width: double.infinity, + height: double.infinity, + color: widget.appBarColor, + child: Column( + children: [ + if (widget.hasAppBar) + SliderAppBar( + slideDirection: widget.slideDirection, + onTap: () => toggle(), + appBarHeight: widget.appBarHeight, + animationController: _animationDrawerController, + appBarColor: widget.appBarColor, + appBarPadding: widget.appBarPadding, + drawerIcon: widget.drawerIcon, + drawerIconColor: widget.drawerIconColor, + drawerIconSize: widget.drawerIconSize, + isTitleCenter: widget.isTitleCenter, + splashColor: widget.splashColor, + title: widget.title ?? '', + trailing: widget.trailing, + ), + Expanded(child: widget.sliderMain), + ], + ), + ), ), ), - ), - ])); + ])); + }); } @override @@ -187,4 +208,88 @@ class SliderMenuContainerState extends State super.dispose(); _animationDrawerController.dispose(); } + + void _onHorizontalDragStart(DragStartDetails detail) { + if (!widget.isDraggable) return; + + //Check use start dragging from left edge / right edge then enable dragging + if ((widget.slideDirection == SlideDirection.LEFT_TO_RIGHT && + detail.localPosition.dx <= WIDTH_GESTURE) || + (widget.slideDirection == SlideDirection.RIGHT_TO_LEFT && + detail.localPosition.dx >= + WIDTH_GESTURE) /*&& + detail.localPosition.dy <= widget.appBarHeight*/ + ) { + this.setState(() { + dragging = true; + }); + } + //Check use start dragging from top edge / bottom edge then enable dragging + if (widget.slideDirection == SlideDirection.TOP_TO_BOTTOM && + detail.localPosition.dy >= HEIGHT_GESTURE) { + this.setState(() { + dragging = true; + }); + } + } + + void _onHorizontalDragEnd(DragEndDetails detail) { + if (!widget.isDraggable) return; + if (dragging) { + openOrClose(); + setState(() { + dragging = false; + }); + } + } + + void _onHorizontalDragUpdate( + DragUpdateDetails detail, + BoxConstraints constraints, + ) { + if (!widget.isDraggable) return; + // open drawer for left/right type drawer + if (dragging && widget.slideDirection == SlideDirection.LEFT_TO_RIGHT || + widget.slideDirection == SlideDirection.RIGHT_TO_LEFT) { + var globalPosition = detail.globalPosition.dx; + globalPosition = globalPosition < 0 ? 0 : globalPosition; + double position = globalPosition / constraints.maxWidth; + var realPosition = widget.slideDirection == SlideDirection.LEFT_TO_RIGHT + ? position + : (1 - position); + move(realPosition); + } + // open drawer for top/bottom type drawer + /*if (dragging && widget.slideDirection == SlideDirection.TOP_TO_BOTTOM) { + var globalPosition = detail.globalPosition.dx; + globalPosition = globalPosition < 0 ? 0 : globalPosition; + double position = globalPosition / constraints.maxHeight; + var realPosition = widget.slideDirection == SlideDirection.TOP_TO_BOTTOM + ? position + : (1 - position); + move(realPosition); + }*/ + + // close drawer for left/right type drawer + if (isDrawerOpen && + (widget.slideDirection == SlideDirection.LEFT_TO_RIGHT || + widget.slideDirection == SlideDirection.RIGHT_TO_LEFT) && + detail.delta.dx < 15) { + closeDrawer(); + } + } + + move(double percent) { + _percent = percent; + _animationDrawerController.value = percent; + _animationDrawerController.notifyListeners(); + } + + openOrClose() { + if (_percent > 0.3) { + openDrawer(); + } else { + closeDrawer(); + } + } }