diff --git a/README.md b/README.md index 6a803d4..3de0a0e 100644 --- a/README.md +++ b/README.md @@ -42,12 +42,13 @@ import 'package:flutter_inner_drawer/inner_drawer.dart'; key: _innerDrawerKey, onTapClose: true, // default false swipe: true, // default true - colorTransition: Color.red, // default Color.black54 - innerDrawerCallback: (a) => print(a ),// return bool + colorTransition: Color.red, // default Color.black54 leftOffset: 0.6, // default 0.4 rightOffset: 0.6,// default 0.4 leftScale: 0.9,// default 1 rightScale: 0.9,// default 1 + verticalOffset: 0.0, // default 0 + overlay: false, // default false borderRadius: 50, // default 0 leftAnimationType: InnerDrawerAnimation.static, // default static rightAnimationType: InnerDrawerAnimation.quadratic, @@ -61,6 +62,7 @@ import 'package:flutter_inner_drawer/inner_drawer.dart'; }, innerDrawerCallback: (a) => print(a), // return true (open) or false (close) + leftChild: Container(), // required if rightChild is not set rightChild: Container(), // required if leftChild is not set @@ -102,6 +104,8 @@ import 'package:flutter_inner_drawer/inner_drawer.dart'; |`rightChild`|*Inner Widget*|required if leftChild is not set| |`leftOffset`|*Offset drawer width*|0.4| |`rightOffset`|*Offset drawer width*|0.4| +|`verticalOffset`|*Offset main widget vertically according to height factor*|0.0| +|`overlay`|*If set to true, drawer will appear behind main widget*|false| |`leftScale`|*Left scaffold scaling*|1| |`rightScale`|*Right scaffold scaling*|1| |`borderRadius`|*For scaffold border*|0| @@ -123,4 +127,4 @@ If you found this project helpful or you learned something from the source code - [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/dnag88) ## Issues -If you encounter problems, open an issue. Pull request are also welcome. \ No newline at end of file +If you encounter problems, open an issue. Pull request are also welcome. diff --git a/example/ios/Flutter/flutter_export_environment.sh b/example/ios/Flutter/flutter_export_environment.sh old mode 100644 new mode 100755 index 0d01568..7e7eb69 --- a/example/ios/Flutter/flutter_export_environment.sh +++ b/example/ios/Flutter/flutter_export_environment.sh @@ -1,10 +1,11 @@ #!/bin/sh # This is a generated file; do not edit or check into version control. -export "FLUTTER_ROOT=C:\src\flutter" -export "FLUTTER_APPLICATION_PATH=D:\Android-Project\flutter\package\inner_drawer\flutter_inner_drawer\example" -export "FLUTTER_TARGET=lib\main.dart" +export "FLUTTER_ROOT=/Users/luisfreire/development/flutter" +export "FLUTTER_APPLICATION_PATH=/Users/luisfreire/Projects/OpenSource/Flutter/flutter_inner_drawer/example" +export "FLUTTER_TARGET=/Users/luisfreire/Projects/OpenSource/Flutter/flutter_inner_drawer/example/lib/main.dart" export "FLUTTER_BUILD_DIR=build" -export "SYMROOT=${SOURCE_ROOT}/../build\ios" -export "FLUTTER_FRAMEWORK_DIR=C:\src\flutter\bin\cache\artifacts\engine\ios" +export "SYMROOT=${SOURCE_ROOT}/../build/ios" +export "FLUTTER_FRAMEWORK_DIR=/Users/luisfreire/development/flutter/bin/cache/artifacts/engine/ios" export "FLUTTER_BUILD_NAME=1.0.0" export "FLUTTER_BUILD_NUMBER=1" +export "TRACK_WIDGET_CREATION=true" diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 06c7bbc..94fbec2 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -39,7 +38,6 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; @@ -71,7 +69,6 @@ 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( - 2D5378251FAA1A9400D5DBA9 /* flutter_assets */, 3B80C3931E831B6300D905FE /* App.framework */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 9740EEBA1CF902C7004384FC /* Flutter.framework */, @@ -187,7 +184,6 @@ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/example/lib/example_3.dart b/example/lib/example_3.dart new file mode 100644 index 0000000..537fc6d --- /dev/null +++ b/example/lib/example_3.dart @@ -0,0 +1,363 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_inner_drawer/inner_drawer.dart'; + +class ExampleThree extends StatefulWidget { + ExampleThree({Key key}) : super(key: key); + + @override + _ExampleThreeState createState() => _ExampleThreeState(); +} + +class _ExampleThreeState extends State { + final GlobalKey _innerDrawerKey = + GlobalKey(); + + GlobalKey _keyRed = GlobalKey(); + double _width = 10; + + bool _onTapToClose = false; + bool _swipe = true; + bool _tapScaffold = true; + InnerDrawerAnimation _animationType = InnerDrawerAnimation.static; + double _offset = 0.4; + double _scale = 1; + double _borderRadius = 20; + double _verticalOffset = 0.05; + + AnimationController _animationController; + Animation _bkgColor; + + String _title = "Two"; + + @override + void initState() { + _getwidthContainer(); + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + Color currentColor = Colors.black54; + + void _getwidthContainer() { + WidgetsBinding.instance.addPostFrameCallback((_) { + final keyContext = _keyRed.currentContext; + if (keyContext != null) { + final RenderBox box = keyContext.findRenderObject(); + final size = box.size; + setState(() { + _width = size.width; + }); + } + }); + } + + @override + Widget build(BuildContext context) { + return InnerDrawer( + key: _innerDrawerKey, + onTapClose: true, + leftOffset: _offset, + rightOffset: _offset, + overlay: true, + leftScale: _scale, + rightScale: _scale, + verticalOffset: _verticalOffset, + borderRadius: _borderRadius, + swipe: _swipe, + colorTransition: currentColor, + leftAnimationType: _animationType, + rightAnimationType: _animationType, + leftChild: Material( + child: Container( + decoration: BoxDecoration( + color: Colors.blue[300], + gradient: new RadialGradient( + colors: [Colors.red, Colors.cyan, Colors.purple, Colors.lightGreenAccent], + center: Alignment(0, 0), + radius: 2, + tileMode: TileMode.clamp, + stops: [0.3, 0.5, 0.6, 0.7] + ) + ), + child: Center( + child: Container( + child: Text( + "Left Child", + style: TextStyle(fontSize: 18), + ), + ), + )), + ), + rightChild: Material( + color: Theme.of(context).backgroundColor, + child: Center( + child: Container( + child: Text( + "Right Child", + style: TextStyle(fontSize: 18), + ), + ), + )), + scaffold: Container( + width: double.infinity, + padding: EdgeInsets.symmetric(vertical: 30), + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomLeft, + //stops: [0.1, 0.5,0.5, 0.7, 0.9], + colors: [ + Colors.blue, + Colors.indigo, + ], + ), + ), + child: SafeArea( + child: Material( + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + GestureDetector( + child: Row( + children: [ + Text('Static'), + Checkbox( + activeColor: Colors.black, + value: + _animationType == InnerDrawerAnimation.static, + onChanged: (a) { + setState(() { + _animationType = InnerDrawerAnimation.static; + }); + }), + ], + ), + onTap: () { + setState(() { + _animationType = InnerDrawerAnimation.static; + }); + }, + ), + GestureDetector( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Checkbox( + activeColor: Colors.black, + value: + _animationType == InnerDrawerAnimation.linear, + onChanged: (a) { + setState(() { + _animationType = InnerDrawerAnimation.linear; + }); + }), + Text('Linear'), + ], + ), + onTap: () { + setState(() { + _animationType = InnerDrawerAnimation.linear; + }); + }, + ), + GestureDetector( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Checkbox( + activeColor: Colors.black, + value: _animationType == + InnerDrawerAnimation.quadratic, + onChanged: (a) { + setState(() { + _animationType = + InnerDrawerAnimation.quadratic; + }); + }), + Text('Quadratic'), + ], + ), + onTap: () { + setState(() { + _animationType = InnerDrawerAnimation.quadratic; + }); + }, + ), + ], + ), + Padding( + padding: EdgeInsets.all(10), + ), + Column( + children: [ + Text('Offset'), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SliderTheme( + data: Theme.of(context).sliderTheme.copyWith( + valueIndicatorTextStyle: Theme.of(context) + .accentTextTheme + .body2 + .copyWith(color: Colors.white), + ), + child: Slider( + activeColor: Colors.black, + //inactiveColor: Colors.white, + value: _offset, + min: 0.0, + max: 1, + divisions: 5, + semanticFormatterCallback: (double value) => + value.round().toString(), + label: '$_offset', + onChanged: (a) { + setState(() { + _offset = a; + }); + }, + onChangeEnd: (a) { + //_getwidthContainer(); + }, + ), + ), + Text(_offset.toString()), + //Text(_fontSize.toString()), + ], + ), + ], + ), + Padding( + padding: EdgeInsets.all(10), + ), + Column( + children: [ + Text('Scale'), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SliderTheme( + data: Theme.of(context).sliderTheme.copyWith( + valueIndicatorTextStyle: Theme.of(context) + .accentTextTheme + .body2 + .copyWith(color: Colors.white), + ), + child: Slider( + activeColor: Colors.black, + //inactiveColor: Colors.white, + value: _scale, + min: 0.0, + max: 1, + divisions: 10, + semanticFormatterCallback: (double value) => + value.round().toString(), + label: '$_scale', + onChanged: (a) { + setState(() { + _scale = a; + }); + }, + ), + ), + Text(_scale.toString()), + //Text(_fontSize.toString()), + ], + ), + ], + ), + Padding( + padding: EdgeInsets.all(10), + ), + Column( + children: [ + Text('Border Radius'), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SliderTheme( + data: Theme.of(context).sliderTheme.copyWith( + valueIndicatorTextStyle: Theme.of(context) + .accentTextTheme + .body2 + .copyWith(color: Colors.white), + ), + child: Slider( + activeColor: Colors.black, + //inactiveColor: Colors.white, + value: _borderRadius, + min: 0, + max: 100, + divisions: 4, + semanticFormatterCallback: (double value) => + value.round().toString(), + label: '$_borderRadius', + onChanged: (a) { + setState(() { + _borderRadius = a; + }); + }, + ), + ), + Text(_borderRadius.toString()), + //Text(_fontSize.toString()), + ], + ), + ], + ), + Padding( + padding: EdgeInsets.all(10), + ), + Column( + children: [ + Text('Vertical Offset'), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SliderTheme( + data: Theme.of(context).sliderTheme.copyWith( + valueIndicatorTextStyle: Theme.of(context) + .accentTextTheme + .body2 + .copyWith(color: Colors.white), + ), + child: Slider( + activeColor: Colors.black, + //inactiveColor: Colors.white, + value: _verticalOffset, + min: 0, + max: 0.5, + divisions: 10, + semanticFormatterCallback: (double value) => + value.round().toString(), + label: '$_verticalOffset', + onChanged: (a) { + setState(() { + _verticalOffset = a; + }); + }, + ), + ), + Text(_verticalOffset.toString()), + //Text(_fontSize.toString()), + ], + ), + ], + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/example/lib/main.dart b/example/lib/main.dart index 80c7813..dd9103f 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -4,6 +4,7 @@ import 'package:flutter/services.dart'; import 'example_1.dart'; import 'example_2.dart'; +import 'example_3.dart'; void main() => runApp(MyApp()); @@ -24,6 +25,7 @@ class MyApp extends StatelessWidget { enum Example { one, two, + three } class MainApp extends StatefulWidget { @@ -105,7 +107,7 @@ class _MainAppState extends State with SingleTickerProviderStateMixin { Transform( transform: Matrix4.translationValues( 0.0, - _translateButton.value * 2, + _translateButton.value * 3, 0.0, ), child: _item(title: "One", example: Example.one), @@ -113,11 +115,19 @@ class _MainAppState extends State with SingleTickerProviderStateMixin { Transform( transform: Matrix4.translationValues( 0.0, - _translateButton.value * 1, + _translateButton.value * 2, 0.0, ), child: _item(title: "Two", example: Example.two), ), + Transform( + transform: Matrix4.translationValues( + 0.0, + _translateButton.value * 1, + 0.0, + ), + child: _item(title: "Three", example: Example.three), + ), _toggle(), ], ), @@ -134,6 +144,9 @@ class _MainAppState extends State with SingleTickerProviderStateMixin { case Example.two: return ExampleTwo(); break; + case Example.three: + return ExampleThree(); + break; } } @@ -154,14 +167,25 @@ class _MainAppState extends State with SingleTickerProviderStateMixin { title, style: TextStyle( fontSize: 11, - color: example == Example.one - ? Colors.green[300] - : Colors.orange[300]), + color: _itemColor(example)), ), ), ); } + Color _itemColor(Example example) { + switch (example) { + case Example.one: + return Colors.green[300]; + case Example.two: + return Colors.orange[300]; + case Example.three: + return Colors.blue[300]; + default: + return Colors.black; + } + } + Widget _toggle() { return new Container( child: FloatingActionButton( diff --git a/lib/inner_drawer.dart b/lib/inner_drawer.dart index f6581f9..abcf290 100644 --- a/lib/inner_drawer.dart +++ b/lib/inner_drawer.dart @@ -45,6 +45,8 @@ class InnerDrawer extends StatefulWidget { @required this.scaffold, this.leftOffset = 0.4, this.rightOffset = 0.4, + this.verticalOffset = 0.0, + this.overlay = false, this.leftScale = 1, this.rightScale = 1, this.borderRadius = 0, @@ -76,6 +78,12 @@ class InnerDrawer extends StatefulWidget { /// Right offset drawer width; default 0.4 final double rightOffset; + /// Vertical offset drawer height; default 0.0 + final double verticalOffset; + + /// Overlay drawer; default false + final bool overlay; + /// Left Transform Scale; (default 0) /// values between 1 and 0 final double leftScale; @@ -355,7 +363,7 @@ class InnerDrawerState extends State /// return widget with specific animation Widget _innerAnimationType(double width, InnerDrawerAnimation animationType) { final Widget container = Container( - width: _width - width, + width: widget.overlay ? MediaQuery.of(context).size.width : _width - width, height: MediaQuery.of(context).size.height, child: _position == InnerDrawerDirection.start ? widget.leftChild @@ -432,34 +440,36 @@ class InnerDrawerState extends State Widget container = Container( key: _drawerKey, - decoration: animationType == InnerDrawerAnimation.linear - ? null - : BoxDecoration( - boxShadow: widget.boxShadow ?? - [ - BoxShadow( - color: Colors.black.withOpacity(0.5), - blurRadius: 5, - ) - ]), - child: widget.scaffold); - - if (widget.borderRadius != 0) - container = ClipRRect( - borderRadius: BorderRadius.circular( - (1 - _controller.value) * widget.borderRadius), - child: container, - ); + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(widget.borderRadius * (1-_controller.value)), + boxShadow: widget.boxShadow ?? + [ + BoxShadow( + color: Colors.black.withOpacity(0.5), + blurRadius: 5, + ) + ]), + child: Material( + animationDuration: Duration(milliseconds: 0), + borderRadius: BorderRadius.circular(widget.borderRadius * (1-_controller.value)), + clipBehavior: Clip.antiAlias, + child: widget.scaffold, + )); double scaleFactor = _position == InnerDrawerDirection.start ? widget.leftScale : widget.rightScale; - if (scaleFactor < 1) - container = Transform.scale( - scale: ((1 - scaleFactor) * _controller.value) + scaleFactor, - child: container, - ); + container = Transform.scale( + scale: ((1 - scaleFactor) * _controller.value) + scaleFactor, + child: container, + ); + + double translateY = MediaQuery.of(context).size.height * widget.verticalOffset; + container = Transform.translate( + offset: Offset(0, translateY * (1 - _controller.value)), + child: container, + ); return container; } @@ -528,8 +538,8 @@ class InnerDrawerState extends State ), ///Trigger - _trigger(AlignmentDirectional.centerStart, widget.leftChild), - _trigger(AlignmentDirectional.centerEnd, widget.rightChild), + _trigger(AlignmentDirectional.topStart, widget.leftChild), + _trigger(AlignmentDirectional.topEnd, widget.rightChild), ///Overlay _overlay(width)