diff --git a/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt b/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt new file mode 100644 index 00000000..1656503f --- /dev/null +++ b/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt @@ -0,0 +1,12 @@ +package com.example.example + +import androidx.annotation.NonNull; +import io.flutter.embedding.android.FlutterActivity +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.plugins.GeneratedPluginRegistrant + +class MainActivity: FlutterActivity() { + override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { + GeneratedPluginRegistrant.registerWith(flutterEngine); + } +} diff --git a/example/lib/main.dart b/example/lib/main.dart index 578306fb..53010060 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,20 +1,33 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/painting.dart'; +import 'package:ui_kit/colors/gf_color.dart'; + import 'package:ui_kit/components/button/gf_button.dart'; + import 'package:ui_kit/components/button/gf_icon_button.dart'; + import 'package:ui_kit/components/badge/gf_button_badge.dart'; + import 'package:ui_kit/components/badge/gf_icon_badge.dart'; + import 'package:ui_kit/components/avatar/gf_avatar.dart'; + import 'package:ui_kit/components/badge/gf_badge.dart'; + import 'package:ui_kit/components/card/gf_card.dart'; -import 'package:ui_kit/components/header_bar/gf_title_bar.dart'; + +import 'package:ui_kit/components/list_tile/gf_list_tile.dart'; + +import 'package:ui_kit/components/image/gf_image_overlay.dart'; + import 'package:ui_kit/components/button_bar/gf_button_bar.dart'; -import 'package:ui_kit/position/gf_position.dart'; + import 'package:ui_kit/types/gf_type.dart'; -import 'package:ui_kit/components/image/gf_image_overlay.dart'; import 'package:ui_kit/shape/gf_shape.dart'; import 'package:ui_kit/components/slider/gf_slider.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:ui_kit/size/gf_size.dart'; +import 'package:ui_kit/position/gf_position.dart'; +import 'package:ui_kit/components/tabs/gf_tabs.dart'; final List imageList = [ "https://cdn.pixabay.com/photo/2017/12/03/18/04/christmas-balls-2995437_960_720.jpg", @@ -23,7 +36,6 @@ final List imageList = [ "https://cdn.pixabay.com/photo/2019/12/20/00/03/road-4707345_960_720.jpg" ]; - void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @@ -33,7 +45,9 @@ class MyApp extends StatelessWidget { title: 'UI_KIT_EXAMPLE', theme: ThemeData( primarySwatch: Colors.blue, + ), + debugShowCheckedModeBanner: false, home: MyHomePage(title: 'UI_KIT_EXAMPLE'), ); } @@ -49,79 +63,181 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { + bool switchValue = true; @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), - body: DefaultTabController( - length: 3, - child: Scaffold( - appBar: AppBar( - bottom: TabBar( - tabs: [ - Tab(icon: Icon(Icons.directions_car)), - Tab(icon: Icon(Icons.directions_transit)), - Tab(icon: Icon(Icons.directions_bike)), - ], - ), - title: Text('Tabs Demo'), - ), - body: TabBarView( - children: [ - Icon(Icons.directions_car), - Icon(Icons.directions_transit), - Icon(Icons.directions_bike), - ], - ), - ), - ), -// SingleChildScrollView( -// child: Column( -// mainAxisAlignment: MainAxisAlignment.center, -// crossAxisAlignment: CrossAxisAlignment.center, -// children: [ - - + backgroundColor: Colors.orange, + appBar: AppBar( + title: Text(widget.title), + ), + body: SingleChildScrollView( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ +// Container( +// height: 300.0, +// child: DefaultTabController( +// length: 2, +// child: Scaffold( +// appBar: AppBar( +// bottom: TabBar( +// indicator: UnderlineTabIndicator( +// borderSide: BorderSide(color: Color(0xDD613896), width: 2.0), +// insets: EdgeInsets.fromLTRB(5.0, 0.0, 5.0, 4.0), +// ), +// tabs: [ +// Tab(icon: Icon(Icons.directions_car), text: "Non persistent",), +// Tab(icon: Icon(Icons.directions_transit), text: "Persistent"), +// ], +// ), +// title: Text('Persistent Tab Demo'), +// ), +// body: TabBarView( +// children: [ +// Text("cdx"), +// Text("cdv") +// ], +// ), +// ), +// ), +// ), // GFSlider( //// pagerSize: 12.0, //// activeIndicator: Colors.pink, //// passiveIndicator: Colors.pink.withOpacity(0.4), -// viewportFraction: 0.9, -// aspectRatio: 2.0, +// viewportFraction: 0.9, +// aspectRatio: 2.0, //// autoPlay: true, -// enlargeMainPage: true, -// pagination: true, -// items: imageList.map( -// (url) { -// return Container( -// margin: EdgeInsets.all(5.0), -// child: ClipRRect( -// borderRadius: BorderRadius.all(Radius.circular(5.0)), -// child: Image.network( -// url, -// fit: BoxFit.cover, -// width: 1000.0, +// enlargeMainPage: true, +// pagination: true, +// items: imageList.map( +// (url) { +// return Container( +// margin: EdgeInsets.all(5.0), +// child: ClipRRect( +// borderRadius: BorderRadius.all(Radius.circular(5.0)), +// child: Image.network( +// url, +// fit: BoxFit.cover, +// width: 1000.0, +// ), // ), -// ), -// ); +// ); +// }, +// ).toList(), +// onPageChanged: (index) { +// setState(() { +// index; +// }); // }, -// ).toList(), -// onPageChanged: (index) { -// setState(() { -// index; -// }); -// }, -// ), +// ), + RawMaterialButton(onPressed: null, child: Text("fv"),), + FlatButton(onPressed: null, child: Text("cds")), + +// Container( +// decoration: BoxDecoration( +// color: Colors.teal, +// boxShadow: [BoxShadow( +// color: Colors.pink, +// blurRadius: 1.5, +// spreadRadius: 2.0, +// offset: Offset.zero, +// ) +// ] +// ), +// child: OutlineButton(child: Text("Fvd"),)), +// +// + GFButton( + color: Colors.orange, + onPressed: null, + child: Text("share"), + type: GFType.outline, + shape: GFShape.pills, + buttonBoxShadow: true, + boxShadow: BoxShadow( + color: Colors.pink.withOpacity(0.4), + blurRadius: 1.5, + spreadRadius: 2.0, + offset: Offset.zero, + ), + ), + + GFTabs( + initialIndex: 0, + length: 3, + tabs: [ + GFButton( + onPressed: null, + child: Text("share"), + icon: Icon(Icons.share), + buttonBoxShadow: true, + ), + Tab( + icon: Icon(Icons.error), + child: Text( + "Orders", + ), + ), + Tab( + child: Text( + "Pastry", + ), + ), + ], + tabBarView: TabBarView( + children: [ + Container( + color: Colors.red, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + RawMaterialButton(onPressed: null, child: Text("fv"),), + FlatButton(onPressed: null, child: Text("cds")), + Icon(Icons.directions_railway), + GFButton( + onPressed: null, + child: Text("share"), + icon: Icon(Icons.share), + shape: GFShape.pills, + type: GFType.transparent, + ), + ], + ), + ), + Icon(Icons.directions_car), + Icon(Icons.directions_transit), + ], + ), +// indicatorColor: Colors.teal, +// indicatorSize: TabBarIndicatorSize.label, +// labelColor: Colors.lightGreen, +// unselectedLabelColor: Colors.black, +// labelStyle: TextStyle( +// fontWeight: FontWeight.w500, +// fontSize: 13.0, +// color: Colors.deepOrange, +// fontFamily: 'OpenSansBold', +// ), +// unselectedLabelStyle: TextStyle( +// fontWeight: FontWeight.w500, +// fontSize: 13.0, +// color: Colors.black, +// fontFamily: 'OpenSansBold', +// ), + ), // GFSlider( // autoPlay: true, // viewportFraction: 1.0, // aspectRatio: MediaQuery.of(context).size.aspectRatio, -// items: imageList.map((url) { +// items: imageList.map( +// (url) { // return Container( // margin: EdgeInsets.all(5.0), // child: ClipRRect( @@ -141,68 +257,78 @@ class _MyHomePageState extends State { // }); // }, // ), - -// GFCard( -// boxFit: BoxFit.cover, -// colorFilter: new ColorFilter.mode( -// Colors.black.withOpacity(0.67), BlendMode.darken), -// image: Image.asset("lib/assets/food.jpeg"), -//// imageOverlay: AssetImage("lib/assets/food.jpeg"), -// titlePosition: GFPosition.end, -// title: GFTitleBar( -// avatar: GFAvatar( -// child: Text("tb"), -// ), -// title: Text( -// 'title', -// style: TextStyle(color: Colors.grey), -// ), -// subTitle: Text( -// 'subtitle', -// style: TextStyle(color: Colors.grey), -// ), -// icon: GFIconButton( -// onPressed: null, -// icon: Icon(Icons.favorite_border), -// type: GFType.transparent, -// ), -// ), -// content: Text( -// "Flutter " -// "Flutter is Google's mobile UI framework for crafting" -// " high-quality native interfaces on iOS and Android in " -// "Flutter ", -// style: TextStyle(color: Colors.grey), -// ), -// buttonBar: GFButtonBar( -// mainAxisSize: MainAxisSize.min, -// children: [ -// GFButton( -// onPressed: null, -// child: Text("favorite"), -// icon: Icon(Icons.favorite_border), -// type: GFType.transparent, -// ), -// GFButton( -// onPressed: null, -// child: Text("share"), -// icon: Icon(Icons.share), -// type: GFType.outline, -// ), -// ], -// ), -// ), - -// GFButtonBar( -// mainAxisSize: MainAxisSize.min, -// children: [ -// GFButton(onPressed: null, child: Text("like"), icon: Icon(Icons.favorite_border), type: GFType.transparent,), -// GFButton(onPressed: null, child: Text("comment"),), -// GFButton(onPressed: null, child: Text("share"), icon: Icon(Icons.share), type: GFType.outline,), -// ], -// ), -// -// GFTitleBar( + GFCard( + boxFit: BoxFit.cover, + colorFilter: new ColorFilter.mode( + Colors.black.withOpacity(0.67), BlendMode.darken), + image: Image.asset("lib/assets/food.jpeg"), +// imageOverlay: AssetImage("lib/assets/food.jpeg"), + titlePosition: GFPosition.end, + title: GFListItem( + avatar: GFAvatar( + child: Text("tb"), + ), + title: Text( + 'title', + style: TextStyle(color: Colors.grey), + ), + subTitle: Text( + 'subtitle', + style: TextStyle(color: Colors.grey), + ), + icon: GFIconButton( + onPressed: null, + icon: Icon(Icons.favorite_border), + type: GFType.transparent, + ), + ), + content: Text( + "Flutter " + "Flutter is Google's mobile UI framework for crafting" + " high-quality native interfaces on iOS and Android in " + "Flutter ", + style: TextStyle(color: Colors.grey), + ), + buttonBar: GFButtonBar( + mainAxisSize: MainAxisSize.min, + children: [ + GFButton( + onPressed: null, + child: Text("favorite"), + icon: Icon(Icons.favorite_border), + type: GFType.transparent, + ), + GFButton( + onPressed: null, + child: Text("share"), + icon: Icon(Icons.share), + type: GFType.outline, + ), + ], + ), + ), + GFButtonBar( + mainAxisSize: MainAxisSize.min, + children: [ + GFButton( + onPressed: null, + child: Text("like"), + icon: Icon(Icons.favorite_border), + type: GFType.transparent, + ), + GFButton( + onPressed: null, + child: Text("comment"), + ), + GFButton( + onPressed: null, + child: Text("share"), + icon: Icon(Icons.share), + type: GFType.outline, + ), + ], + ), +// GFListItem( // avatar: GFAvatar( // child: Text("tb"), // ), @@ -214,81 +340,86 @@ class _MyHomePageState extends State { // icon: Icon(Icons.favorite_border), // ), // ), - -// GFImageOverlay( -// width: MediaQuery.of(context).size.width, -// margin: EdgeInsets.all(16.0), -// padding: EdgeInsets.all(16.0), -// child: Column( -// children: [ -// new Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// new Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// new Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// new Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// new Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// new Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// new Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// new Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// new Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// new Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// new Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// new Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// ], -// ), +// GFImageOverlay( +// width: MediaQuery.of(context).size.width, +// margin: EdgeInsets.all(16.0), +// padding: EdgeInsets.all(16.0), +// child: Column( +// children: [ +// new Text( +// 'Hello world', +// style: TextStyle(color: Colors.white), +// ), +// new Text( +// 'Hello world', +// style: TextStyle(color: Colors.white), +// ), +// new Text( +// 'Hello world', +// style: TextStyle(color: Colors.white), +// ), +// new Text( +// 'Hello world', +// style: TextStyle(color: Colors.white), +// ), +// new Text( +// 'Hello world', +// style: TextStyle(color: Colors.white), +// ), +// new Text( +// 'Hello world', +// style: TextStyle(color: Colors.white), +// ), +// new Text( +// 'Hello world', +// style: TextStyle(color: Colors.white), +// ), +// new Text( +// 'Hello world', +// style: TextStyle(color: Colors.white), +// ), +// new Text( +// 'Hello world', +// style: TextStyle(color: Colors.white), +// ), +// new Text( +// 'Hello world', +// style: TextStyle(color: Colors.white), +// ), +// new Text( +// 'Hello world', +// style: TextStyle(color: Colors.white), +// ), +// new Text( +// 'Hello world', +// style: TextStyle(color: Colors.white), +// ), +// ], +// ), //// color: Colors.orange, -// image: AssetImage("lib/assets/food.jpeg"), -// boxFit: BoxFit.cover, -// colorFilter: new ColorFilter.mode( -// Colors.black.withOpacity(0.6), BlendMode.darken), -// borderRadius: new BorderRadius.circular(5.0), +// image: AssetImage("lib/assets/food.jpeg"), +// boxFit: BoxFit.cover, +// colorFilter: new ColorFilter.mode( +// Colors.black.withOpacity(0.6), BlendMode.darken), +// borderRadius: new BorderRadius.circular(5.0), //// border: Border.all(color: Colors.pink, width: 2.0), -// ), - -// +// ), // GFAvatar( -//// radius: 40.0, +// // radius: 20.0, +//// maxRadius: 50, +// // child: Text("de"), -// backgroundColor: Colors.pink, -//// backgroundImage: , +// +//// backgroundColor: Colors.pink, +//// +////// backgroundImage: , +//// //// foregroundColor: Colors.deepOrangeAccent, -//// shape: GFShape.square, +//// +//// shape: GFShape.square, +//// //// size: GFSize.medium, +//// //// borderRadius: BorderRadius.circular(20.0), // ), // GFIconBadges( @@ -299,12 +430,19 @@ class _MyHomePageState extends State { // ), // counterChild: GFBadge( // text: '12', +// //// color: GFColor.dark, +//// //// shape: GFShape.circle, +//// //// size: GFSize.small, +//// //// border: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid), +//// //// textColor: GFColor.white, +//// //// textStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: 8.0), +//// //// borderShape: RoundedRectangleBorder(side: BorderSide(color: Colors.orange, width: 2.0, style: BorderStyle.solid), borderRadius: BorderRadius.zero), // ), // ), @@ -336,15 +474,15 @@ class _MyHomePageState extends State { //// shape: GFShape.pills, //// type: GFType.outline, //// size: GFSize.small, -// counterChild: GFBadge( -// child: Text("12"), +// counterChild: GFBadge( +// child: Text("12"), //// color: GFColor.dark, //// shape: GFShape.circle, //// size: GFSize.small, //// border: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid), //// textColor: GFColor.white, //// textStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: 8.0), -// ), +// ), // ), // GFBadge( // text: '12', @@ -378,9 +516,9 @@ class _MyHomePageState extends State { //// borderSide: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid), //// borderShape: RoundedRectangleBorder(side: BorderSide(color: Colors.pink, width: 2.0, style: BorderStyle.solid), borderRadius: BorderRadius.zero), // ), -// ], -// ), -// ) + ], + ), + ), ); } } diff --git a/lib/colors/gf_color.dart b/lib/colors/gf_color.dart index 0175c29f..f7a256d2 100644 --- a/lib/colors/gf_color.dart +++ b/lib/colors/gf_color.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; + enum GFColor { primary, secondary, @@ -12,19 +13,22 @@ enum GFColor { light, dark, white, + transparent } -const PRIMARY = Colors.blue; -const SECONDARY = Colors.grey; -const SUCCESS = Colors.green; -const INFO = Colors.yellow; -const WARNING = Colors.lightBlueAccent; -const DANGER = Colors.red; -const FOCUS = Colors.black38; -const ALT = Colors.purple; -const LIGHT = Colors.white30; -const DARK = Colors.black; -const WHITE = Colors.white; + +const PRIMARY = Color(0xff3f6ad8); +const SECONDARY = Color(0xff6c757c); +const SUCCESS =Color(0xff3ac47c); +const INFO = Color(0xff13aaff); +const WARNING = Color(0xfff7b825); +const DANGER = Color(0xffd92550); +const FOCUS = Color(0xff434054); +const ALT = Color(0xff794c8a); +const LIGHT = Color(0xffededed); +const DARK = Color(0xff333a40); +const WHITE = Color(0xffffffff); +const TRANSPARENT = Colors.transparent; /// Pass [GFColor] or [Color] Color getGFColor(dynamic color) { @@ -65,6 +69,9 @@ Color getGFColor(dynamic color) { case GFColor.white: return WHITE; break; + case GFColor.transparent: + return TRANSPARENT; + break; default: return PRIMARY; break; diff --git a/lib/components/badge/gf_button_badge.dart b/lib/components/badge/gf_button_badge.dart index 3dd55974..7d706fa3 100644 --- a/lib/components/badge/gf_button_badge.dart +++ b/lib/components/badge/gf_button_badge.dart @@ -111,7 +111,8 @@ class _GFButtonBadgeState extends State { position: this.position, size: this.size, borderShape: widget.borderShape, - icon: widget.counterChild), + icon: widget.counterChild + ), ), ); } diff --git a/lib/components/button/gf_button.dart b/lib/components/button/gf_button.dart index 6e2b1628..58a86555 100644 --- a/lib/components/button/gf_button.dart +++ b/lib/components/button/gf_button.dart @@ -10,6 +10,7 @@ import 'package:ui_kit/types/gf_type.dart'; import 'package:ui_kit/position/gf_position.dart'; import 'package:ui_kit/colors/gf_color.dart'; + class GFButton extends StatefulWidget { /// Called when the button is tapped or otherwise activated. final VoidCallback onPressed; @@ -116,6 +117,37 @@ class GFButton extends StatefulWidget { /// on true state default box shadow appears around button final bool buttonBoxShadow; + /// A set of thirteen colors that can be used to derive the button theme's + /// colors. + /// + /// This property was added much later than the theme's set of highly + /// specific colors, like [ThemeData.buttonColor], [ThemeData.highlightColor], + /// [ThemeData.splashColor] etc. + /// + /// The colors for new button classes can be defined exclusively in terms + /// of [colorScheme]. When it's possible, the existing buttons will + /// (continue to) gradually migrate to it. + final ColorScheme colorScheme; + + /// Whether detected gestures should provide acoustic and/or haptic feedback. + /// + /// For example, on Android a tap will produce a clicking sound and a + /// long-press will produce a short vibration, when feedback is enabled. + /// + /// See also: + /// + /// * [Feedback] for providing platform-specific feedback to certain actions. + final bool enableFeedback; + + /// Called when the button is long-pressed. + /// + /// If this callback and [onPressed] are null, then the button will be disabled. + /// + /// See also: + /// + /// * [enabled], which is true if the button is enabled. + final VoidCallback onLongPress; + /// Create buttons of all types. check out [GFIconButton] for icon buttons, and [GFBadge] for badges const GFButton({ Key key, @@ -153,8 +185,11 @@ class GFButton extends StatefulWidget { this.icon, this.blockButton, this.fullWidthButton, + this.colorScheme, + this.enableFeedback, + this.onLongPress }) : materialTapTargetSize = - materialTapTargetSize ?? MaterialTapTargetSize.padded, + materialTapTargetSize ?? MaterialTapTargetSize.padded, assert(shape != null, 'Button shape can not be null'), assert(elevation != null && elevation >= 0.0), assert(focusElevation != null && focusElevation >= 0.0), @@ -266,30 +301,37 @@ class _GFButtonState extends State { super.didUpdateWidget(oldWidget); } - // double get _effectiveElevation { - // // These conditionals are in order of precedence, so be careful about - // // reorganizing them. - // if (_disabled) { - // return widget.disabledElevation; - // } - // if (_pressed) { - // return widget.highlightElevation; - // } - // if (_hovered) { - // return widget.hoverElevation; - // } - // if (_focused) { - // return widget.focusElevation; - // } - // return widget.elevation; - // } + + double get _effectiveElevation { + // These conditionals are in order of precedence, so be careful about + // reorganizing them. + if (_disabled) { + return widget.disabledElevation; + } + if (_pressed) { + return widget.highlightElevation; + } + if (_hovered) { + return widget.hoverElevation; + } + if (_focused) { + return widget.focusElevation; + } + return widget.elevation; + } + @override Widget build(BuildContext context) { + + ShapeBorder shape; + + final ShapeBorder effectiveShape = MaterialStateProperty.resolveAs(shape, _states); + final Color effectiveTextColor = MaterialStateProperty.resolveAs( widget.textStyle?.color, _states); final Color themeColor = - Theme.of(context).colorScheme.onSurface.withOpacity(0.12); + Theme.of(context).colorScheme.onSurface.withOpacity(0.12); final BorderSide outlineBorder = BorderSide( color: widget.borderSide == null ? themeColor : widget.borderSide.color, width: widget.borderSide?.width ?? 1.0, @@ -311,13 +353,13 @@ class _GFButtonState extends State { final BorderSide shapeBorder = widget.type == GFType.outline ? outlineBorder : widget.borderSide != null - ? widget.borderSide - : BorderSide( - color: this.color, - width: 0.0, - ); + ? widget.borderSide + : BorderSide( + color: this.color == null ? themeColor : this.color, + width: 0.0, + ); + - ShapeBorder shape; if (this.shape == GFShape.pills) { shape = RoundedRectangleBorder( @@ -333,99 +375,127 @@ class _GFButtonState extends State { borderRadius: BorderRadius.circular(50.0), side: shapeBorder); } + BoxDecoration getBoxShadow() { + if(widget.type != GFType.transparent){ + if(widget.boxShadow == null && widget.buttonBoxShadow != true){ + return null; + }else{ + return BoxDecoration( + color: widget.type == GFType.transparent || widget.type == GFType.outline ? Colors.transparent : this.color, + borderRadius: widget.shape == GFShape.pills ? BorderRadius.circular(50.0) : + widget.shape == GFShape.standard ? BorderRadius.circular(5.0) : BorderRadius.zero, + boxShadow: [ + widget.boxShadow == null && widget.buttonBoxShadow == true ? BoxShadow( + color: themeColor, + blurRadius: 1.5, + spreadRadius: 2.0, + offset: Offset.zero, + ) : + widget.boxShadow != null ? widget.boxShadow : + BoxShadow( + color: Theme.of(context).canvasColor, + blurRadius: 0.0, + spreadRadius: 0.0, + offset: Offset.zero, + ) + ] + ); + } + } + } - return Semantics( - container: true, - button: true, - enabled: widget.enabled, - child: _InputPadding( - minSize: minSize, - child: Focus( - focusNode: widget.focusNode, - onFocusChange: _handleFocusedChanged, - autofocus: widget.autofocus, - child: Container( - constraints: this.icon == null ? BoxConstraints(minHeight: 26.0, minWidth: 88.0) : - BoxConstraints(minHeight: 26.0, minWidth: 98.0), - decoration: BoxDecoration( - borderRadius: widget.shape == GFShape.pills ? BorderRadius.circular(50.0) : - widget.shape == GFShape.standard ? BorderRadius.circular(5.0) : BorderRadius.zero, - boxShadow: [ - widget.boxShadow == null && widget.buttonBoxShadow == true ? BoxShadow( - color: this.color.withOpacity(0.4), - blurRadius: 1.5, - spreadRadius: 2.0, - offset: Offset.zero, - ) : - widget.boxShadow != null ? widget.boxShadow : - BoxShadow( - color: Theme.of(context).canvasColor, - blurRadius: 0.0, - spreadRadius: 0.0, - offset: Offset.zero, - ) - ] - ), - child: Material( - textStyle: widget.textStyle == null ? TextStyle(color: this.textColor, fontSize: 14) : widget.textStyle, - shape: widget.type == GFType.transparent ? null : widget.borderShape== null ? shape : widget.borderShape, - color: widget.type != GFType.outline || widget.type == null ? this.color : Theme.of(context).canvasColor, - type: widget.type == GFType.transparent ? MaterialType.transparency : MaterialType.button, - animationDuration: widget.animationDuration, - clipBehavior: widget.clipBehavior, - child: InkWell( - onHighlightChanged: _handleHighlightChanged, - splashColor: widget.splashColor, - highlightColor: widget.highlightColor, - focusColor: widget.focusColor, - hoverColor: widget.hoverColor, - onHover: _handleHoveredChanged, - onTap: widget.onPressed, - customBorder: widget.borderShape == null ? shape : widget.borderShape, - child: IconTheme.merge( - data: IconThemeData(color: effectiveTextColor), - child: Container( - height: widget.blockButton == true ? BLOCK - : widget.fullWidthButton == true ? BLOCK - : this.size, - width: buttonWidth(), - padding: widget.padding, - child: Center( - widthFactor: 1.0, - heightFactor: 1.0, - child: this.icon != null && (this.position == GFPosition.start || this.position == null)? - Row( - mainAxisSize: MainAxisSize.min, - children: [ - this.icon, - const SizedBox(width: 8.0), - this.child - ], - ) - : this.icon != null && - (this.position == GFPosition.end) - ? Row( - mainAxisSize: MainAxisSize.min, - children: [ - this.child, - const SizedBox(width: 8.0), - this.icon - ], - ) - : this.child, - ), - ), - ), + + final Widget result = Container( + constraints: this.icon == null ? BoxConstraints(minHeight: 26.0, minWidth: 88.0) : + BoxConstraints(minHeight: 26.0, minWidth: 98.0), + decoration: getBoxShadow(), + child: Material( + elevation: _effectiveElevation, + textStyle: widget.textStyle == null ? TextStyle(color: this.textColor, fontSize: 14) : widget.textStyle, + shape: widget.type == GFType.transparent ? null : widget.borderShape == null ? shape : widget.borderShape, + color: widget.type == GFType.transparent || widget.type == GFType.outline ? Colors.transparent : this.color, + type: this.color == null ? MaterialType.transparency : MaterialType.button, + animationDuration: widget.animationDuration, + clipBehavior: widget.clipBehavior, + child: InkWell( + onHighlightChanged: _handleHighlightChanged, + splashColor: widget.splashColor, + highlightColor: widget.highlightColor, + focusColor: widget.focusColor, + hoverColor: widget.hoverColor, + onHover: _handleHoveredChanged, + onTap: widget.onPressed, + customBorder: widget.type == GFType.transparent ? null : widget.borderShape == null ? shape : widget.borderShape, + child: IconTheme.merge( + data: IconThemeData(color: effectiveTextColor), + child: Container( + height: widget.blockButton == true ? BLOCK + : widget.fullWidthButton == true ? BLOCK + : this.size, + width: buttonWidth(), + padding: widget.padding, + child: Center( + widthFactor: 1.0, + heightFactor: 1.0, + child: this.icon != null && (this.position == GFPosition.start || this.position == null)? + Row( + mainAxisSize: MainAxisSize.min, + children: [ + this.icon, + const SizedBox(width: 8.0), + this.child + ], + ) + : this.icon != null && + (this.position == GFPosition.end) + ? Row( + mainAxisSize: MainAxisSize.min, + children: [ + this.child, + const SizedBox(width: 8.0), + this.icon + ], + ) + : this.child, ), ), ), ), ), ); + + return Semantics( + container: true, + button: true, + enabled: widget.enabled, + child: _InputPadding( + minSize: minSize, + child: result, + ), + ); + +// return Semantics( +// container: true, +// button: true, +// enabled: widget.enabled, +// child: _InputPadding( +// minSize: minSize, +// child: Focus( +// focusNode: widget.focusNode, +// onFocusChange: _handleFocusedChanged, +// autofocus: widget.autofocus, +// child: +// ), +// ), +// ); } } /// A widget to pad the area around a [MaterialButton]'s inner [Material]. +/// +/// Redirect taps that occur in the padded area around the child to the center +/// of the child. This increases the size of the button and the button's +/// "tap target", but not its material or its ink splashes. class _InputPadding extends SingleChildRenderObjectWidget { const _InputPadding({ Key key, @@ -441,8 +511,7 @@ class _InputPadding extends SingleChildRenderObjectWidget { } @override - void updateRenderObject( - BuildContext context, covariant _RenderInputPadding renderObject) { + void updateRenderObject(BuildContext context, covariant _RenderInputPadding renderObject) { renderObject.minSize = minSize; } } @@ -452,9 +521,9 @@ class _RenderInputPadding extends RenderShiftedBox { Size get minSize => _minSize; Size _minSize; - set minSize(Size value) { - if (_minSize == value) return; + if (_minSize == value) + return; _minSize = value; markNeedsLayout(); } @@ -502,7 +571,7 @@ class _RenderInputPadding extends RenderShiftedBox { } @override - bool hitTest(BoxHitTestResult result, {Offset position}) { + bool hitTest(BoxHitTestResult result, { Offset position }) { if (super.hitTest(result, position: position)) { return true; } @@ -517,3 +586,545 @@ class _RenderInputPadding extends RenderShiftedBox { ); } } + + + +//class GFButton extends StatefulWidget { +// /// Called when the button is tapped or otherwise activated. +// final VoidCallback onPressed; +// +// /// Called by the underlying [InkWell] widget's [InkWell.onHighlightChanged] callback. +// final ValueChanged onHighlightChanged; +// +// /// Defines the default text style, with [Material.textStyle], for the button's [child]. +// final TextStyle textStyle; +// +// /// The border side for the button's [Material]. +// final BorderSide borderSide; +// +// /// The box shadow for the button's [Material]. +// final BoxShadow boxShadow; +// +// /// The color for the button's [Material] when it has the input focus. +// final Color focusColor; +// +// /// The color for the button's [Material] when a pointer is hovering over it. +// final Color hoverColor; +// +// /// The highlight color for the button's [InkWell]. +// final Color highlightColor; +// +// /// The splash color for the button's [InkWell]. +// final Color splashColor; +// +// /// The elevation for the button's [Material] when the button is [enabled] but not pressed. +// final double elevation; +// +// /// The elevation for the button's [Material] when the button is [enabled] and a pointer is hovering over it. +// final double hoverElevation; +// +// /// The elevation for the button's [Material] when the button is [enabled] and has the input focus. +// final double focusElevation; +// +// /// The elevation for the button's [Material] when the button is [enabled] and pressed. +// final double highlightElevation; +// +// /// The elevation for the button's [Material] when the button is not [enabled]. +// final double disabledElevation; +// +// /// The internal padding for the button's [child]. +// final EdgeInsetsGeometry padding; +// +// /// Defines the button's size. +// final BoxConstraints constraints; +// +// /// The shape of the button's [Material]. +// final ShapeBorder borderShape; +// +// /// Defines the duration of animated changes for [shape] and [elevation]. +// final Duration animationDuration; +// +// /// Typically the button's label. +// final Widget child; +// +// /// Whether the button is enabled or disabled. +// bool get enabled => onPressed != null; +// +// /// Configures the minimum size of the tap target. +// final MaterialTapTargetSize materialTapTargetSize; +// +// /// {@macro flutter.widgets.Focus.focusNode} +// final FocusNode focusNode; +// +// /// {@macro flutter.widgets.Focus.autofocus} +// final bool autofocus; +// +// /// {@macro flutter.widgets.Clip} +// final Clip clipBehavior; +// +// /// Button type of [GFType] i.e, solid, outline, dashed +// final GFType type; +// +// /// Button type of [GFShape] i.e, standard, pills, square, shadow, icons +// final GFShape shape; +// +// /// Pass [GFColor] or [Color] +// final dynamic color; +// +// /// Pass [GFColor] or [Color] +// final dynamic textColor; +// +// /// size of [double] or [GFSize] i.e, 1.2, small, medium, large etc. +// final dynamic size; +// +// /// text of type [String] is alternative to child. text will get priority over child +// final String text; +// +// /// icon of type [Widget] +// final Widget icon; +// +// /// icon type of [GFIconPosition] i.e, start, end +// final GFPosition position; +// +// /// on true state blockButton gives block size button +// final bool blockButton; +// +// /// on true state full width Button gives full width button +// final bool fullWidthButton; +// +// /// on true state default box shadow appears around button +// final bool buttonBoxShadow; +// +// /// A set of thirteen colors that can be used to derive the button theme's +// /// colors. +// /// +// /// This property was added much later than the theme's set of highly +// /// specific colors, like [ThemeData.buttonColor], [ThemeData.highlightColor], +// /// [ThemeData.splashColor] etc. +// /// +// /// The colors for new button classes can be defined exclusively in terms +// /// of [colorScheme]. When it's possible, the existing buttons will +// /// (continue to) gradually migrate to it. +// final ColorScheme colorScheme; +// +// /// Create buttons of all types. check out [GFIconButton] for icon buttons, and [GFBadge] for badges +// const GFButton({ +// Key key, +// @required this.onPressed, +// this.onHighlightChanged, +// this.textStyle, +// this.boxShadow, +// this.buttonBoxShadow, +// this.focusColor, +// this.hoverColor, +// this.highlightColor, +// this.splashColor, +// this.elevation = 2.0, +// this.focusElevation = 4.0, +// this.hoverElevation = 4.0, +// this.highlightElevation = 1.0, +// this.disabledElevation = 0.0, +// this.padding = const EdgeInsets.symmetric(horizontal: 8.0), +// this.constraints, +// this.borderShape, +// this.animationDuration = kThemeChangeDuration, +// this.clipBehavior = Clip.none, +// this.focusNode, +// this.autofocus = false, +// MaterialTapTargetSize materialTapTargetSize, +// this.child, +// this.type, +// this.shape = GFShape.standard, +// this.color, +// this.textColor = GFColor.dark, +// this.position = GFPosition.start, +// this.size = GFSize.medium, +// this.borderSide, +// this.text, +// this.icon, +// this.blockButton, +// this.fullWidthButton, +// this.colorScheme, +// }) : materialTapTargetSize = +// materialTapTargetSize ?? MaterialTapTargetSize.padded, +// assert(shape != null, 'Button shape can not be null'), +// assert(elevation != null && elevation >= 0.0), +// assert(focusElevation != null && focusElevation >= 0.0), +// assert(hoverElevation != null && hoverElevation >= 0.0), +// assert(highlightElevation != null && highlightElevation >= 0.0), +// assert(disabledElevation != null && disabledElevation >= 0.0), +// assert(padding != null), +// assert(animationDuration != null), +// assert(clipBehavior != null), +// assert(autofocus != null), +// super(key: key); +// +// @override +// _GFButtonState createState() => _GFButtonState(); +//} +// +//class _GFButtonState extends State { +//// Color color; +// Color textColor; +// Widget child; +// Widget icon; +// Function onPressed; +// GFType type; +// GFShape shape; +// double size; +// GFPosition position; +// BoxShadow boxShadow; +// final Set _states = {}; +// +// @override +// void initState() { +//// this.color = getGFColor(widget.color); +// this.textColor = getGFColor(widget.textColor); +// this.child = widget.text != null ? Text(widget.text) : widget.child; +// this.icon = widget.icon; +// this.onPressed = widget.onPressed; +// this.type = widget.type; +// this.shape = widget.shape; +// this.size = getGFSize(widget.size); +// this.position = widget.position; +// _updateState(MaterialState.disabled, !widget.enabled); +// super.initState(); +// } +// +// bool get _hovered => _states.contains(MaterialState.hovered); +// bool get _focused => _states.contains(MaterialState.focused); +// bool get _pressed => _states.contains(MaterialState.pressed); +// bool get _disabled => _states.contains(MaterialState.disabled); +// +// double blockWidth(context) { +// return MediaQuery.of(context).size.width * 0.88; +// } +// +// double fullWidth(context) { +// return MediaQuery.of(context).size.width; +// } +// +// double buttonWidth() { +// if (widget.blockButton == true) { +// return blockWidth(context); +// } else if (widget.fullWidthButton == true) { +// return fullWidth(context); +// } else { +// return null; +// } +// } +// +// void _updateState(MaterialState state, bool value) { +// value ? _states.add(state) : _states.remove(state); +// } +// +// void _handleHighlightChanged(bool value) { +// if (_pressed != value) { +// setState(() { +// _updateState(MaterialState.pressed, value); +// if (widget.onHighlightChanged != null) { +// widget.onHighlightChanged(value); +// } +// }); +// } +// } +// +// void _handleHoveredChanged(bool value) { +// if (_hovered != value) { +// setState(() { +// _updateState(MaterialState.hovered, value); +// }); +// } +// } +// +// void _handleFocusedChanged(bool value) { +// if (_focused != value) { +// setState(() { +// _updateState(MaterialState.focused, value); +// }); +// } +// } +// +// @override +// void didUpdateWidget(GFButton oldWidget) { +// _updateState(MaterialState.disabled, !widget.enabled); +// // If the button is disabled while a press gesture is currently ongoing, +// // InkWell makes a call to handleHighlightChanged. This causes an exception +// // because it calls setState in the middle of a build. To preempt this, we +// // manually update pressed to false when this situation occurs. +// if (_disabled && _pressed) { +// _handleHighlightChanged(false); +// } +// super.didUpdateWidget(oldWidget); +// } +// +// // double get _effectiveElevation { +// // // These conditionals are in order of precedence, so be careful about +// // // reorganizing them. +// // if (_disabled) { +// // return widget.disabledElevation; +// // } +// // if (_pressed) { +// // return widget.highlightElevation; +// // } +// // if (_hovered) { +// // return widget.hoverElevation; +// // } +// // if (_focused) { +// // return widget.focusElevation; +// // } +// // return widget.elevation; +// // } +// +// @override +// Widget build(BuildContext context) { +// final Color effectiveTextColor = MaterialStateProperty.resolveAs( +// widget.textStyle?.color, _states); +// final Color themeColor = +// Theme.of(context).colorScheme.onSurface.withOpacity(0.12); +// final BorderSide outlineBorder = BorderSide( +// color: widget.borderSide == null ? themeColor : widget.borderSide.color, +// width: widget.borderSide?.width ?? 1.0, +// ); +// +// Size minSize; +// switch (widget.materialTapTargetSize) { +// case MaterialTapTargetSize.padded: +// minSize = const Size(48.0, 48.0); +// break; +// case MaterialTapTargetSize.shrinkWrap: +// minSize = Size.zero; +// break; +// default: +// minSize = Size.zero; +// break; +// } +// +// final BorderSide shapeBorder = widget.type == GFType.outline +// ? outlineBorder +// : widget.borderSide != null +// ? widget.borderSide +// : BorderSide( +// color: widget.color, +// width: 0.0, +// ); +// +// ShapeBorder shape; +// +// if (this.shape == GFShape.pills) { +// shape = RoundedRectangleBorder( +// borderRadius: BorderRadius.circular(50.0), side: shapeBorder); +// } else if (this.shape == GFShape.square) { +// shape = RoundedRectangleBorder( +// borderRadius: BorderRadius.circular(0.0), side: shapeBorder); +// } else if (this.shape == GFShape.standard) { +// shape = RoundedRectangleBorder( +// borderRadius: BorderRadius.circular(5.0), side: shapeBorder); +// } else { +// shape = RoundedRectangleBorder( +// borderRadius: BorderRadius.circular(50.0), side: shapeBorder); +// } +// +//// print("ccccccccccccccccccccc ${MaterialButton}"); +// +// Color getFillColor(MaterialButton button) { +// final Color color = button.enabled ? button.color : button.disabledColor; +// if (color != null) +// return color; +// +// if (button is FlatButton || button is OutlineButton || button.runtimeType == MaterialButton) +// return null; +// +// if (button.enabled && button is RaisedButton && widget.color != null) +// return widget.color; +// +// +// assert(false); +// return null; +// } +// +// print('ffffffffff ${ThemeData.disabledColor}'); +// +// return Semantics( +// container: true, +// button: true, +// enabled: widget.enabled, +// child: _InputPadding( +// minSize: minSize, +// child: Focus( +// focusNode: widget.focusNode, +// onFocusChange: _handleFocusedChanged, +// autofocus: widget.autofocus, +// child: Container( +// constraints: this.icon == null ? BoxConstraints(minHeight: 26.0, minWidth: 88.0) : +// BoxConstraints(minHeight: 26.0, minWidth: 98.0), +// decoration: BoxDecoration( +// borderRadius: widget.shape == GFShape.pills ? BorderRadius.circular(50.0) : +// widget.shape == GFShape.standard ? BorderRadius.circular(5.0) : BorderRadius.zero, +// boxShadow: [ +// widget.boxShadow == null && widget.buttonBoxShadow == true ? BoxShadow( +// color: widget.color.withOpacity(0.4), +// blurRadius: 1.5, +// spreadRadius: 2.0, +// offset: Offset.zero, +// ) : +// widget.boxShadow != null ? widget.boxShadow : +// BoxShadow( +// color: Theme.of(context).canvasColor, +// blurRadius: 0.0, +// spreadRadius: 0.0, +// offset: Offset.zero, +// ) +// ] +// ), +// child: Material( +// textStyle: widget.textStyle == null ? TextStyle(color: this.textColor, fontSize: 14) : widget.textStyle, +// shape: widget.type == GFType.transparent ? null : widget.borderShape == null ? shape : widget.borderShape, +// color: ThemeData.disabledColor, +// type: widget.type == GFType.transparent ? MaterialType.transparency : MaterialType.button, +// animationDuration: widget.animationDuration, +// clipBehavior: widget.clipBehavior, +// child: InkWell( +// onHighlightChanged: _handleHighlightChanged, +// splashColor: widget.splashColor, +// highlightColor: widget.highlightColor, +// focusColor: widget.focusColor, +// hoverColor: widget.hoverColor, +// onHover: _handleHoveredChanged, +// onTap: widget.onPressed, +// customBorder: widget.type == GFType.transparent ? null : widget.borderShape == null ? shape : widget.borderShape, +// child: IconTheme.merge( +// data: IconThemeData(color: effectiveTextColor), +// child: Container( +// height: widget.blockButton == true ? BLOCK +// : widget.fullWidthButton == true ? BLOCK +// : this.size, +// width: buttonWidth(), +// padding: widget.padding, +// child: Center( +// widthFactor: 1.0, +// heightFactor: 1.0, +// child: this.icon != null && (this.position == GFPosition.start || this.position == null)? +// Row( +// mainAxisSize: MainAxisSize.min, +// children: [ +// this.icon, +// const SizedBox(width: 8.0), +// this.child +// ], +// ) +// : this.icon != null && +// (this.position == GFPosition.end) +// ? Row( +// mainAxisSize: MainAxisSize.min, +// children: [ +// this.child, +// const SizedBox(width: 8.0), +// this.icon +// ], +// ) +// : this.child, +// ), +// ), +// ), +// ), +// ), +// ), +// ), +// ), +// ); +// } +//} +// +///// A widget to pad the area around a [MaterialButton]'s inner [Material]. +//class _InputPadding extends SingleChildRenderObjectWidget { +// const _InputPadding({ +// Key key, +// Widget child, +// this.minSize, +// }) : super(key: key, child: child); +// +// final Size minSize; +// +// @override +// RenderObject createRenderObject(BuildContext context) { +// return _RenderInputPadding(minSize); +// } +// +// @override +// void updateRenderObject( +// BuildContext context, covariant _RenderInputPadding renderObject) { +// renderObject.minSize = minSize; +// } +//} +// +//class _RenderInputPadding extends RenderShiftedBox { +// _RenderInputPadding(this._minSize, [RenderBox child]) : super(child); +// +// Size get minSize => _minSize; +// Size _minSize; +// +// set minSize(Size value) { +// if (_minSize == value) return; +// _minSize = value; +// markNeedsLayout(); +// } +// +// @override +// double computeMinIntrinsicWidth(double height) { +// if (child != null) +// return math.max(child.getMinIntrinsicWidth(height), minSize.width); +// return 0.0; +// } +// +// @override +// double computeMinIntrinsicHeight(double width) { +// if (child != null) +// return math.max(child.getMinIntrinsicHeight(width), minSize.height); +// return 0.0; +// } +// +// @override +// double computeMaxIntrinsicWidth(double height) { +// if (child != null) +// return math.max(child.getMaxIntrinsicWidth(height), minSize.width); +// return 0.0; +// } +// +// @override +// double computeMaxIntrinsicHeight(double width) { +// if (child != null) +// return math.max(child.getMaxIntrinsicHeight(width), minSize.height); +// return 0.0; +// } +// +// @override +// void performLayout() { +// if (child != null) { +// child.layout(constraints, parentUsesSize: true); +// final double height = math.max(child.size.width, minSize.width); +// final double width = math.max(child.size.height, minSize.height); +// size = constraints.constrain(Size(height, width)); +// final BoxParentData childParentData = child.parentData; +// childParentData.offset = Alignment.center.alongOffset(size - child.size); +// } else { +// size = Size.zero; +// } +// } +// +// @override +// bool hitTest(BoxHitTestResult result, {Offset position}) { +// if (super.hitTest(result, position: position)) { +// return true; +// } +// final Offset center = child.size.center(Offset.zero); +// return result.addWithRawTransform( +// transform: MatrixUtils.forceToPoint(center), +// position: center, +// hitTest: (BoxHitTestResult result, Offset position) { +// assert(position == center); +// return child.hitTest(result, position: center); +// }, +// ); +// } +//} diff --git a/lib/components/button/gf_icon_button.dart b/lib/components/button/gf_icon_button.dart index c169bb99..560a8b35 100644 --- a/lib/components/button/gf_icon_button.dart +++ b/lib/components/button/gf_icon_button.dart @@ -204,6 +204,35 @@ class _GFIconButtonState extends State { ); } + BoxDecoration getBoxShadow() { + if(widget.type != GFType.transparent){ + if(widget.boxShadow == null && widget.buttonBoxShadow != true){ + return null; + }else{ + return BoxDecoration( + color: widget.type == GFType.transparent || widget.type == GFType.outline ? Colors.transparent : this.color, + borderRadius: widget.shape == GFShape.pills ? BorderRadius.circular(50.0) : + widget.shape == GFShape.standard ? BorderRadius.circular(5.0) : BorderRadius.zero, + boxShadow: [ + widget.boxShadow == null && widget.buttonBoxShadow == true ? BoxShadow( + color: themeColor, + blurRadius: 1.5, + spreadRadius: 2.0, + offset: Offset.zero, + ) : + widget.boxShadow != null ? widget.boxShadow : + BoxShadow( + color: Theme.of(context).canvasColor, + blurRadius: 0.0, + spreadRadius: 0.0, + offset: Offset.zero, + ) + ] + ); + } + } + } + return Semantics( button: true, enabled: widget.onPressed != null, @@ -216,36 +245,12 @@ class _GFIconButtonState extends State { height: widget.shape == GFShape.pills ? this.height + 6 : this.height, width: widget.shape == GFShape.pills ? this.width + 6 : this.width, - decoration: BoxDecoration( - borderRadius: widget.shape == GFShape.pills - ? BorderRadius.circular(50.0) - : widget.shape == GFShape.standard - ? BorderRadius.circular(5.0) - : BorderRadius.zero, - boxShadow: [ - widget.boxShadow == null && widget.buttonBoxShadow == true - ? BoxShadow( - color: this.color.withOpacity(0.4), - blurRadius: 1.5, - spreadRadius: 2.0, - offset: Offset.zero, - ) - : widget.boxShadow != null - ? widget.boxShadow - : BoxShadow( - color: Theme.of(context).canvasColor, - blurRadius: 0.0, - spreadRadius: 0.0, - offset: Offset.zero, - ) - ]), + decoration: getBoxShadow(), child: Material( shape: widget.type == GFType.transparent ? null : widget.borderShape == null ? shape : widget.borderShape, - color: widget.type != GFType.outline || widget.type == null - ? this.color - : Theme.of(context).canvasColor, + color: widget.type == GFType.transparent || widget.type == GFType.outline ? Colors.transparent : this.color, type: widget.type == GFType.transparent ? MaterialType.transparency : MaterialType.button, diff --git a/lib/components/card/gf_card.dart b/lib/components/card/gf_card.dart index 93ca4e30..1d1e479f 100644 --- a/lib/components/card/gf_card.dart +++ b/lib/components/card/gf_card.dart @@ -1,7 +1,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:ui_kit/components/button_bar/gf_button_bar.dart'; -import 'package:ui_kit/components/header_bar/gf_title_bar.dart'; +import 'package:ui_kit/components/list_tile/gf_list_tile.dart'; import 'package:ui_kit/components/image/gf_image_overlay.dart'; import 'package:ui_kit/position/gf_position.dart'; @@ -62,7 +62,7 @@ class GFCard extends StatelessWidget { final bool semanticContainer; /// The title to display inside the [GFTitleBar]. see [GFTitleBar] - final GFTitleBar title; + final GFListItem title; /// widget can be used to define content final Widget content; @@ -106,9 +106,9 @@ class GFCard extends StatelessWidget { titlePosition == GFPosition.start ? image != null ? image : Container(): title != null ? title : Container(), Padding( padding: padding, - child: content, + child: content != null ? content : Container(), ), - buttonBar, + buttonBar == null ? Container() : buttonBar, ], ); diff --git a/lib/components/header/gf_header.dart b/lib/components/header/gf_header.dart new file mode 100644 index 00000000..1aadb06d --- /dev/null +++ b/lib/components/header/gf_header.dart @@ -0,0 +1,114 @@ +import 'package:flutter/material.dart'; +import 'package:ui_kit/colors/gf_color.dart'; + +class GFHeader extends StatelessWidget { + const GFHeader( + {Key key, + this.child, + this.text, + this.icon, + this.dividerBorderRadius, + this.textColor, + this.dividerAlignment, + this.dividerColor, + this.showDivider = true, + this.dividerWidth, + this.backgroundImage, + this.backgroundImagecolorFilter}) + : super(key: key); + + + /// child of type [Widget] is alternative to text key. text will get priority over child + final Widget child; + + /// text of type [String] is alternative to child. text will get priority over child + final String text; + + ///icon of type [Widget] used to pass icon or image + final Widget icon; + + /// Pass [GFColor] or [Color] for dividerColor + final dynamic dividerColor; + + /// Pass [GFColor] or [Color] for textColor + final dynamic textColor; + + /// dividerBorderRadius of type [BorderRadius] to alter the radius of the divider + final BorderRadius dividerBorderRadius; + + ///dividerAlignment of type [Alignment] used for aligning the divider to required alignment + final Alignment dividerAlignment; + + ///Pass [bool] value to show or hide the divider + final bool showDivider; + + ///pass [double] type to increase or decrease the width of the divider + final double dividerWidth; + + ///backgroundImage of type [ImageProvider] to set the background of [GFHeader] + final ImageProvider backgroundImage; + + ///backgroundImagecolorFilter of type [ColorFilter] to set the background color of [GFHeader] only when backgroundImage is available + final ColorFilter backgroundImagecolorFilter; + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.all(backgroundImage != null ? 10 : 0), + decoration: BoxDecoration( + image: backgroundImage != null + ? DecorationImage( + image: backgroundImage, + fit: BoxFit.cover, + colorFilter: backgroundImagecolorFilter ?? + ColorFilter.mode(Colors.black54, BlendMode.darken), + ) + : null, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + icon != null ? icon : Container(), + icon != null + ? Padding(padding: EdgeInsets.only(left: 10)) + : Container(), + text != null + ? Text( + text, + style: TextStyle( + color: textColor != null + ? getGFColor(textColor) + : backgroundImage != null + ? Colors.white + : Colors.black, + fontSize: 16, + letterSpacing: 0.3, + fontWeight: FontWeight.w500), + ) + : child + ], + ), + showDivider + ? Container( + margin: EdgeInsets.only(top: 5, bottom: 5), + alignment: dividerAlignment, + child: Container( + width: dividerWidth != null ? dividerWidth : 70, + height: 4, + decoration: BoxDecoration( + color: dividerColor != null + ? getGFColor(dividerColor) + : backgroundImage != null + ? Colors.white + : Colors.black, + borderRadius: dividerBorderRadius != null + ? dividerBorderRadius + : BorderRadius.all(Radius.circular(5))), + )) + : Container() + ], + )); + } +} diff --git a/lib/components/header_bar/gf_title_bar.dart b/lib/components/list_tile/gf_list_tile.dart similarity index 54% rename from lib/components/header_bar/gf_title_bar.dart rename to lib/components/list_tile/gf_list_tile.dart index 34791b54..900f352e 100644 --- a/lib/components/header_bar/gf_title_bar.dart +++ b/lib/components/list_tile/gf_list_tile.dart @@ -2,33 +2,25 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:ui_kit/components/avatar/gf_avatar.dart'; -class GFTitleBar extends StatelessWidget { +class GFListItem extends StatelessWidget { /// The card's background color. final Color color; - /// The empty space that surrounds the card. Defines the card's outer [Container.margin]. - final EdgeInsetsGeometry margin; - - /// The empty space that surrounds the card. Defines the card's outer [Container.padding]. - final EdgeInsetsGeometry padding; - /// [GFAvatar] used to create rounded user profile final GFAvatar avatar; - /// The title to display inside the [GFTitleBar]. see [Text] + /// The title to display inside the [GFListItem]. see [Text] final Widget title; - /// The subTitle to display inside the [GFTitleBar]. see [Text] + /// The subTitle to display inside the [GFListItem]. see [Text] final Widget subTitle; - /// The icon to display inside the [GFTitleBar]. see [Icon] + /// The icon to display inside the [GFListItem]. see [Icon] final Widget icon; - const GFTitleBar( + const GFListItem( {Key key, this.color, - this.padding, - this.margin, this.avatar, this.title, this.subTitle, diff --git a/lib/components/slider/gf_slider.dart b/lib/components/slider/gf_slider.dart index ce04c443..852403e4 100644 --- a/lib/components/slider/gf_slider.dart +++ b/lib/components/slider/gf_slider.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:ffi'; import 'package:flutter/material.dart'; List map(List list, Function handler) { diff --git a/lib/components/tabs/gf_tabs.dart b/lib/components/tabs/gf_tabs.dart index e69de29b..6226d7cf 100644 --- a/lib/components/tabs/gf_tabs.dart +++ b/lib/components/tabs/gf_tabs.dart @@ -0,0 +1,206 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter/widgets.dart'; +import 'package:ui_kit/components/button/gf_button.dart'; + + +class GFTabs extends StatefulWidget { + GFTabs({ + Key key, + this.initialIndex = 0, + @required this.length, + this.height, + this.tabBarColor, + this.indicatorColor, + this.indicatorWeight = 2.0, + this.indicatorPadding = EdgeInsets.zero, + this.indicator, + this.indicatorSize, + this.labelColor, + this.labelStyle, + this.labelPadding, + this.unselectedLabelColor, + this.unselectedLabelStyle, + this.tabBarView, + this.tabs, + }): + assert(length != null && length >= 0), + assert(initialIndex != null && initialIndex >= 0 && (length == 0 || initialIndex < length)); + + /// The initial index of the selected tab. Defaults to zero. + final int initialIndex; + + /// The total number of tabs. Typically greater than one. Must match [TabBar.tabs]'s and + /// [TabBarView.children]'s length. + final int length; + + /// Sets [GFTabs] height + final double height; + + /// Sets [TabBar] color using material color [Color] + final Color tabBarColor; + + /// The color of the line that appears below the selected tab. + /// + /// If this parameter is null, then the value of the Theme's indicatorColor + /// property is used. + /// + /// If [indicator] is specified, this property is ignored. + final Color indicatorColor; + + /// The thickness of the line that appears below the selected tab. + /// + /// The value of this parameter must be greater than zero and its default + /// value is 2.0. + /// + /// If [indicator] is specified, this property is ignored. + final double indicatorWeight; + + /// The horizontal padding for the line that appears below the selected tab. + /// + /// For [isScrollable] tab bars, specifying [kTabLabelPadding] will align + /// the indicator with the tab's text for [Tab] widgets and all but the + /// shortest [Tab.text] values. + /// + /// The [EdgeInsets.top] and [EdgeInsets.bottom] values of the + /// [indicatorPadding] are ignored. + /// + /// The default value of [indicatorPadding] is [EdgeInsets.zero]. + /// + /// If [indicator] is specified, this property is ignored. + final EdgeInsetsGeometry indicatorPadding; + + /// Defines the appearance of the selected tab indicator. + /// + /// If [indicator] is specified, the [indicatorColor], [indicatorWeight], + /// and [indicatorPadding] properties are ignored. + /// + /// The default, underline-style, selected tab indicator can be defined with + /// [UnderlineTabIndicator]. + /// + /// The indicator's size is based on the tab's bounds. If [indicatorSize] + /// is [TabBarIndicatorSize.tab] the tab's bounds are as wide as the space + /// occupied by the tab in the tab bar. If [indicatorSize] is + /// [TabBarIndicatorSize.label], then the tab's bounds are only as wide as + /// the tab widget itself. + final Decoration indicator; + + /// Defines how the selected tab indicator's size is computed. + /// + /// The size of the selected tab indicator is defined relative to the + /// tab's overall bounds if [indicatorSize] is [TabBarIndicatorSize.tab] + /// (the default) or relative to the bounds of the tab's widget if + /// [indicatorSize] is [TabBarIndicatorSize.label]. + /// + /// The selected tab's location appearance can be refined further with + /// the [indicatorColor], [indicatorWeight], [indicatorPadding], and + /// [indicator] properties. + final TabBarIndicatorSize indicatorSize; + + /// The color of selected tab labels. + /// + /// Unselected tab labels are rendered with the same color rendered at 70% + /// opacity unless [unselectedLabelColor] is non-null. + /// + /// If this parameter is null, then the color of the [ThemeData.primaryTextTheme]'s + /// body2 text color is used. + final Color labelColor; + + /// The color of unselected tab labels. + /// + /// If this property is null, unselected tab labels are rendered with the + /// [labelColor] with 70% opacity. + final Color unselectedLabelColor; + + /// The text style of the selected tab labels. + /// + /// If [unselectedLabelStyle] is null, then this text style will be used for + /// both selected and unselected label styles. + /// + /// If this property is null, then the text style of the + /// [ThemeData.primaryTextTheme]'s body2 definition is used. + final TextStyle labelStyle; + + /// The padding added to each of the tab labels. + /// + /// If this property is null, then kTabLabelPadding is used. + final EdgeInsetsGeometry labelPadding; + + /// The text style of the unselected tab labels + /// + /// If this property is null, then the [labelStyle] value is used. If [labelStyle] + /// is null, then the text style of the [ThemeData.primaryTextTheme]'s + /// body2 definition is used. + final TextStyle unselectedLabelStyle; + + /// One widget per tab. + /// Its length must match the length of the [GFTabs.tabs] + /// list, as well as the [controller]'s [GFTabs.length]. + final TabBarView tabBarView; + + /// Typically a list of two or more [Tab] widgets. + /// + /// The length of this list must match the [controller]'s [TabController.length] + /// and the length of the [TabBarView.children] list. + final List tabs; + + + @override + _GFTabsState createState() => _GFTabsState(); +} + +class _GFTabsState extends State { + @override + Widget build(BuildContext context) { + return Container( + child: DefaultTabController( + initialIndex: widget.initialIndex, + length: widget.length, + child: Container( + height: widget.height == null ? MediaQuery.of(context).size.height * 0.5 : widget.height, + child: Column( + children: [ + Material( + type: MaterialType.button, + color: widget.tabBarColor ?? Theme.of(context).primaryColor, + child: TabBar( + labelColor: widget.labelColor, + unselectedLabelColor: widget.unselectedLabelColor, + labelStyle: widget.labelStyle, + unselectedLabelStyle: widget.unselectedLabelStyle, + indicatorColor: widget.indicatorColor, + indicatorSize: widget.indicatorSize, + indicator: widget.indicator, + indicatorPadding: widget.indicatorPadding, + indicatorWeight: widget.indicatorWeight, + tabs: widget.tabs, + ), + ), + Expanded( + child: widget.tabBarView + ), + ], + ), + ), + ), + ); + } +} + + + + + + + + + + + + + + + + + diff --git a/lib/components/toast/gf_toast.dart b/lib/components/toast/gf_toast.dart new file mode 100644 index 00000000..b3d0af01 --- /dev/null +++ b/lib/components/toast/gf_toast.dart @@ -0,0 +1,58 @@ +import 'package:flutter/material.dart'; +import 'package:ui_kit/colors/gf_color.dart'; + +class GFToast extends StatelessWidget { + + /// + GFToast({Key key, + this.child, + this.button, + this.backgroundColor, + this.text, + this.textStyle = const TextStyle(color: Colors.white70), + }) :super(key: key); + + /// child of type [Widget]is alternative to text key. text will get priority over child + final Widget child; + + /// button of type [Widget],or you can use [GFButton] for easy implementation with [GFToast] + final Widget button; + + ///pass color of type [Color] or [GFColor] for background of [GFToast] + final dynamic backgroundColor; + + /// text of type [String] is alternative to child. text will get priority over child + final String text; + + /// textStyle will be applicable to text only and not for the child + final TextStyle textStyle; + + + @override + Widget build(BuildContext context) { + return + ConstrainedBox(constraints: BoxConstraints(minHeight: 50.0,), child: Container( + margin: EdgeInsets.only(left: 10, right: 10), + padding: EdgeInsets.all(10), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(3)), + color: backgroundColor!=null ?getGFColor(backgroundColor):Color(0xff323232), + ), + child: Row( + children: [ + Flexible( + flex: 7, + fit: FlexFit.tight, + child: text!=null ? Text(text , style: textStyle):(child??Container()),), + SizedBox( + width: 10, + ), + button!=null?Flexible( + flex: 4, + fit: FlexFit.tight, + child: button):Container() + ], + ), + ),); + } +} \ No newline at end of file diff --git a/lib/components/toggle/gf_toggle.dart b/lib/components/toggle/gf_toggle.dart index 60384abb..bf86b7ae 100644 --- a/lib/components/toggle/gf_toggle.dart +++ b/lib/components/toggle/gf_toggle.dart @@ -2,631 +2,199 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import '../../types/gf_toggle_type.dart'; +class GFToggle extends StatefulWidget { + GFToggle( + {Key key, + @required this.onChanged, + @required this.value, + this.enabledText, + this.disabledText, + this.enabledTextStyle, + this.enabledThumbColor, + this.enabledTrackColor, + this.disabledTextStyle, + this.disabledTrackColor, + this.disabledThumbColor, + this.type, + this.boxShape, + this.borderRadius, + this.duration}) + : super(key: key); + ///type [String] used to add custom text i.e, ON,ENABLE + final String enabledText; + ///type [String] used to add custom text i.e, ON,DISABLE + final String disabledText; -class GFToggle extends StatelessWidget { - GFToggle({Key key, - @required this.onChanged, - @required this.value, - this.activeColor, -// this.inactiveColor, - this.inactiveTrackColor, - this.inactiveThumbColor, - this.activeThumbColor, - this.focusColor, - this.hoverColor, - this.type, - this.height, - this.width, - this.onText, - this.offText, - this.minWidth - }) :super(key: key); - - -// /// Button type of [GFToggleType] i.e, androidSwitch, iosSwitch, labeledSwitch, animatedSWitch - GFToggleType type; - - ///A androidSwitch - /// - /// The color to use on the track when this switch is on. - final Color activeColor; - - - /// Whether this switch is on or off. - /// - /// This property must not be null. - final bool value; - - ///the state used to toggle the switch for true or false - final ValueChanged onChanged; - - /// The color to use on the track when this switch is off. - final Color inactiveTrackColor; - - /// Defaults to the colors described in the Material design specification. - final Color inactiveThumbColor; - - /// Defaults to the colors described in the Material design specification when switch is on. - final Color activeThumbColor; - - - /// The color for the button's [Material] when it has the input focus. - final Color focusColor; - - /// The color for the button's [Material] when a pointer is hovering over it. - final Color hoverColor; - - - ///height of the ios button - final double height; - - ///width of the track button - final double width; - - -///text for the labeled Switch when it is true - final String onText; - -///text for the labled switch when it is false - final String offText; - - - ///minwidth of the switch for labeled switch - final bool minWidth; - - - @override - Widget build(BuildContext context) { - if (type == GFToggleType.androidSwitch) { - return Switch( - value: value, - activeColor: activeColor, - inactiveThumbColor: inactiveTrackColor, - inactiveTrackColor: inactiveTrackColor, -// hoverColor: hoverColor, -// focusColor: focusColor, - onChanged: onChanged, - - - ); - } else if (type == GFToggleType.iosSwitch) { - return CupertinoSwitch( - value: value, - onChanged: onChanged, - activeColor: activeColor, - - - ); - - } else if (type == GFToggleType.labeledSwitch){ - return Switch(value: value, onChanged: onChanged, + ///type of [TextStyle] used to define the style properties of the enabled text + final TextStyle enabledTextStyle; + ///type of [TextStyle] used to define the style peoperties of the disabled text + final TextStyle disabledTextStyle; +// ///type of [Color] used for the active thumb color + final Color enabledThumbColor; - ); + ///type of [Color] used for the inactive thumb color + final Color disabledThumbColor; + ///type of [Color] used for the active track color + final Color enabledTrackColor; - } - } -} -// -//enum TextTransitionTypes { ROTATE, SCALE, FADE, SIZE } -// -//class LabeledToggle extends StatefulWidget { -// final Widget child; -// final String onText; -// final String offText; -// final Color onTextColor; -// final Color offTextColor; -// final Color onThumbColor; -// final Color offThumbColor; -// final Color onBorderColor; -// final Color offBorderColor; -// final Color onBkColor; -// final Color offBkColor; -// final bool value; -// final double thumbSize; -// final double borderSize; -// final Duration duration; -// final Curve curve; -// final ValueChanged onChanged; -// final bool forceWidth; -// final bool rounded; -// final TextTransitionTypes transitionType; -// final bool rotationAnimation; -// -// const LabeledToggle( -// {Key key, -// this.value = false, -// this.onText = "", -// this.offText = "", -// this.onThumbColor, -// this.offThumbColor, -// this.onBorderColor, -// this.offBorderColor, -// this.onBkColor, -// this.offBkColor, -// this.onChanged, -// @required this.thumbSize, -// this.duration = const Duration(milliseconds: 400), -// this.curve = Curves.linear, -// this.forceWidth = false, -// this.onTextColor = Colors.black, -// this.offTextColor = Colors.black, -// this.rounded = true, -// this.borderSize = 1.0, -// this.transitionType = TextTransitionTypes.SCALE, -// this.rotationAnimation = false, -// this.child}) -// : assert(thumbSize != null), -// super(key: key); -// -// const LabeledToggle.theme( -// {Key key, -// this.value = false, -// this.onText = "", -// this.offText = "", -// @required onColor, -// @required offColor, -// this.onChanged, -// @required this.thumbSize, -// this.duration = const Duration(milliseconds: 400), -// this.curve = Curves.linear, -// this.forceWidth = false, -// this.rounded = true, -// this.borderSize = 1.0, -// this.transitionType = TextTransitionTypes.SCALE, -// this.rotationAnimation = false, -// this.child}) -// : assert(thumbSize != null), -// onThumbColor = offColor, -// onBorderColor = offColor, -// onBkColor = onColor, -// offThumbColor = onColor, -// offBorderColor = onColor, -// offBkColor = offColor, -// onTextColor = offColor, -// offTextColor = onColor, -// super(key: key); -// -// @override -// _LabeledToggleState createState() => _LabeledToggleState(); -//} -// -//class _LabeledToggleState extends State -// with SingleTickerProviderStateMixin { -// bool _value; -// AnimationController animationController; -// Animation animation; -// -// @override -// void initState() { -// super.initState(); -// _value = widget.value; -// animationController = -// AnimationController(vsync: this, duration: widget.duration); -// CurvedAnimation curvedAnimation = -// CurvedAnimation(parent: animationController, curve: widget.curve); -// animation = Tween(begin: 0.0, end: 180.0).animate(curvedAnimation) -// ..addListener(() { -// setState(() {}); -// }); -// } -// -// @override -// void dispose() { -// animationController.dispose(); -// -// super.dispose(); -// } -// -// @override -// void didUpdateWidget(LabeledToggle oldWidget) { -// super.didUpdateWidget(oldWidget); -// _value = widget.value; -// } -// -// @override -// Widget build(BuildContext context) { -// return GestureDetector( -// onTap: () { -// widget.onChanged == null ? print("") : widget.onChanged(!_value); -// if (widget.rotationAnimation) { -// if (animationController.status == AnimationStatus.completed) { -// animationController.reverse(); -// } else { -// animationController.forward(); -// } -// } -// }, -// child: Opacity( -// opacity: widget.onChanged == null ? 0.3 : 1.0, -// child: AnimatedContainer( -// duration: widget.duration, -// height: widget.thumbSize, -// width: widget.forceWidth ? widget.thumbSize * 1.7 : null, -// child: Stack( -// children: [ -// Padding( -// padding: const EdgeInsets.only(top:1.5, bottom: 1.5), -// child: AnimatedAlign( -// curve: widget.curve, -// -// alignment: _value ? Alignment.centerRight : Alignment.centerLeft, -// duration: widget.duration, -// child: RotationTransition( -// turns: AlwaysStoppedAnimation(animation.value / 360), -// child: AnimatedContainer( -// duration: widget.duration, -// width: widget.thumbSize, -// height: widget.thumbSize, -// child: widget?.child, -// decoration: BoxDecoration( -// shape: widget.rounded ? BoxShape.circle : BoxShape.rectangle, -// color: _value ? widget.onThumbColor : widget.offThumbColor, -// ), -// ), -// ), -// ), -// ), -// Padding( -// padding: EdgeInsets.only( -// right: _value ? widget.thumbSize : 1, -// left: _value ? 1.0 : widget.thumbSize), -// child: Row( -// children: [ -//// Expanded(child: Text('l')), -// Expanded( -// child: Padding( -// padding: const EdgeInsets.all(0), -// child: Container( -// height: widget.thumbSize, -// child: FittedBox( -// child: Center( -// child: AnimatedSwitcher( -// duration: widget.duration, -// switchInCurve: widget.curve, -// switchOutCurve: widget.curve, -// transitionBuilder: -// (Widget child, Animation animation) { -// switch (widget.transitionType) { -// case TextTransitionTypes.ROTATE: -// { -// return RotationTransition( -// child: child, -// turns: animation, -// ); -// } -// break; -// case TextTransitionTypes.FADE: -// { -// return FadeTransition( -// child: child, -// opacity: animation, -// ); -// } -// break; -// -// case TextTransitionTypes.SIZE: -// { -// return SizeTransition( -// child: child, -// sizeFactor: animation, -// axisAlignment: widget.value ? -5.0 : 5.0, -// axis: Axis.horizontal, -// ); -// } -// break; -// -// case TextTransitionTypes.SCALE: -// { -// return ScaleTransition( -// child: child, -// scale: animation, -// ); -// } -// break; -// } -// }, -// child: Text( -// _value ? widget.onText : widget.offText, -// key: ValueKey(_value), -// style: TextStyle( -// color: _value -// ? widget.onTextColor -// : widget.offTextColor), -// ), -// ), -// ), -// ), -// ), -// ), -// ), -// ], -// ), -// ) -// ], -// ), -// decoration: BoxDecoration( -// border: Border.all( -// color: widget.onChanged == null -// ? Color(0xFFD3D3D3) -// : _value -// ? (widget.onBorderColor ?? widget.onThumbColor) -// : (widget.offBorderColor ?? widget.offThumbColor), -// width: widget.borderSize), -// color: _value ? widget.onBkColor : widget.offBkColor, -// borderRadius: -// BorderRadius.circular(widget.rounded ? 100.0 : 0.0)), -// ), -// ), -// ); -// } -// -// -// } + ///type of [Color] used for the inactive thumb color + final Color disabledTrackColor; + ///type of [BoxShape] used to define shapes i.e, Circle , Rectangle + final BoxShape boxShape; + ///type of [BorderRadius] used to define the radius of the Container + final BorderRadius borderRadius; + ///type of animation [Duration] called when the switch animates during the specific duration + final Duration duration; -enum TextTransitionTypes { ROTATE, SCALE, FADE, SIZE } + /// Button type of [GFToggleType] i.e, android, ios, custom, sqaure + GFToggleType type; -class LabeledToggle extends StatefulWidget { - final Widget child; - final String onText; - final String offText; - final Color onTextColor; - final Color offTextColor; - final Color onThumbColor; - final Color offThumbColor; - final Color onBorderColor; - final Color offBorderColor; - final Color onBkColor; - final Color offBkColor; + /// This property must not be null. Used to set the current state of toggle final bool value; - final double thumbSize; - final double borderSize; - final Duration duration; - final Curve curve; - final ValueChanged onChanged; - final bool forceWidth; - final bool rounded; - final TextTransitionTypes transitionType; - final bool rotationAnimation; - - const LabeledToggle( - {Key key, - this.value = false, - this.onText = "", - this.offText = "", - this.onThumbColor, - this.offThumbColor, - this.onBorderColor, - this.offBorderColor, - this.onBkColor, - this.offBkColor, - this.onChanged, - @required this.thumbSize, - this.duration = const Duration(milliseconds: 400), - this.curve = Curves.linear, - this.forceWidth = false, - this.onTextColor = Colors.black, - this.offTextColor = Colors.black, - this.rounded = true, - this.borderSize = 1.0, - this.transitionType = TextTransitionTypes.SCALE, - this.rotationAnimation = false, - this.child}) - : assert(thumbSize != null), - super(key: key); - const LabeledToggle.theme( - {Key key, - this.value = false, - this.onText = "", - this.offText = "", - @required onColor, - @required offColor, - this.onChanged, - @required this.thumbSize, - this.duration = const Duration(milliseconds: 400), - this.curve = Curves.linear, - this.forceWidth = false, - this.rounded = true, - this.borderSize = 1.0, - this.transitionType = TextTransitionTypes.SCALE, - this.rotationAnimation = false, - this.child}) - : assert(thumbSize != null), - onThumbColor = offColor, - onBorderColor = offColor, - onBkColor = onColor, - offThumbColor = onColor, - offBorderColor = onColor, - offBkColor = offColor, - onTextColor = offColor, - offTextColor = onColor, - super(key: key); + /// Called when the user toggles the switch on or off. + final ValueChanged onChanged; - @override - _LabeledToggleState createState() => _LabeledToggleState(); + @override + _GFToggleState createState() => _GFToggleState(); } -class _LabeledToggleState extends State - with SingleTickerProviderStateMixin { - bool _value; +class _GFToggleState extends State with TickerProviderStateMixin { AnimationController animationController; Animation animation; + AnimationController controller; + Animation offset; + + bool isOn = false; @override void initState() { super.initState(); - _value = widget.value; - animationController = - AnimationController(vsync: this, duration: widget.duration); - CurvedAnimation curvedAnimation = - CurvedAnimation(parent: animationController, curve: widget.curve); - animation = Tween(begin: 0.0, end: 180.0).animate(curvedAnimation) - ..addListener(() { - setState(() {}); - }); + controller = AnimationController(vsync: this, duration: widget.duration); + offset = Tween(begin: Offset.zero, end: Offset(1.0, 0.0)).animate(controller); } @override void dispose() { animationController.dispose(); - super.dispose(); } - @override - void didUpdateWidget(LabeledToggle oldWidget) { - super.didUpdateWidget(oldWidget); - _value = widget.value; - } - @override Widget build(BuildContext context) { return GestureDetector( onTap: () { - widget.onChanged == null ? print("") : widget.onChanged(!_value); - if (widget.rotationAnimation) { - if (animationController.status == AnimationStatus.completed) { - animationController.reverse(); - } else { - animationController.forward(); - } + setState(() { + isOn = !isOn; + }); + switch (controller.status) { + case AnimationStatus.dismissed: + controller.forward(); + break; + case AnimationStatus.completed: + controller.reverse(); + break; + default: + } + if(widget.onChanged!=null){ + widget.onChanged(isOn); } - }, - child: - - Opacity( - opacity: widget.onChanged == null ? 0.3 : 1.0, - child: AnimatedContainer( - duration: widget.duration, - height: 20, - width: 40, -// width: widget.forceWidth ? widget.thumbSize * 1.4 : null, - child: Stack( - children: [ - AnimatedAlign( - curve: widget.curve, - alignment: _value ? Alignment.centerRight : Alignment.centerLeft, - duration: widget.duration, - child: RotationTransition( - turns: AlwaysStoppedAnimation(animation.value / 360), - child: AnimatedContainer( - duration: widget.duration, - width: widget.thumbSize, - height: 150, - child: widget?.child, - decoration: BoxDecoration( - shape: widget.rounded ? BoxShape.circle : BoxShape.rectangle, - color: _value ? widget.onThumbColor : widget.offThumbColor, + }, + child: Stack( + children: [ + Container( + height: widget.type == GFToggleType.android ? 25 : 30, + width: widget.type == GFToggleType.android ? 40 : 50, + ), + Positioned( + top: 5, + child: Container( + width: widget.type == GFToggleType.ios ? 45 : 36, + height: widget.type == GFToggleType.ios ? 25 : 15, + decoration: BoxDecoration( + color: isOn + ? widget.enabledTrackColor ?? Colors.lightGreen + : widget.disabledTrackColor ?? Colors.grey, + borderRadius: widget.type == GFToggleType.square + ? BorderRadius.all(Radius.circular(0)) + : widget.borderRadius ?? + BorderRadius.all(Radius.circular(20))), + child: Padding( + padding: widget.type == GFToggleType.ios ? EdgeInsets.only(left: 3.5, right: 3.5, top: 5.4): EdgeInsets.only(left: 3, right: 3, top: 3.4), + child: isOn + ? Text( + widget.enabledText ?? + ( widget.type == GFToggleType.custom + ? 'ON' + : ''), + style: widget.enabledTextStyle ?? + ( widget.type == GFToggleType.ios ?TextStyle(color: Colors.white, fontSize: 12): TextStyle(color: Colors.white, fontSize: 8)) + ) + : Text( + widget.disabledText ?? + ( widget.type == GFToggleType.custom + ? 'OFF' + : ''), + textAlign: TextAlign.end, + style: widget.disabledTextStyle ?? + ( widget.type == GFToggleType.ios ?TextStyle(color: Colors.white, fontSize: 12): TextStyle(color: Colors.white, fontSize: 8)) + ))), + ), + Positioned( + top: widget.type == GFToggleType.ios ? 7.5 : 3, + left: widget.type == GFToggleType.ios ? 2 : 0, + child: GestureDetector( + onTap: () { + setState(() { + isOn = !isOn; + }); + switch (controller.status) { + case AnimationStatus.dismissed: + controller.forward(); + break; + case AnimationStatus.completed: + controller.reverse(); + break; + default: + } + if(widget.onChanged!=null){ + widget.onChanged(isOn); + } + }, + child: SlideTransition( + position: offset, + child: Container( + padding: EdgeInsets.only(left: 10), + height: 20, + width: 20, + decoration: BoxDecoration( + shape: widget.type == GFToggleType.square + ? BoxShape.rectangle + : widget.boxShape ?? BoxShape.circle, + color: isOn ? widget.enabledThumbColor ?? Colors.white + : widget.disabledThumbColor ?? Colors.white, + boxShadow: [ + new BoxShadow( + color: Colors.black.withOpacity(0.16), + blurRadius: 6.0, + spreadRadius: 0.0), + ]), ), - ), - ), - ), - Positioned( - - child: Padding( - padding: EdgeInsets.only( - right: _value ? widget.thumbSize : 1, - left: _value ? 2.0 : widget.thumbSize), - child: Row( - children: [ -// Expanded(child: Text('l')), - Expanded( - child: Padding( - padding: const EdgeInsets.all(0), - child: Container( - width: 80, - height: 100, - child: FittedBox( - child: Center( - child: AnimatedSwitcher( - duration: widget.duration, - switchInCurve: widget.curve, - switchOutCurve: widget.curve, - transitionBuilder: - (Widget child, Animation animation) { - switch (widget.transitionType) { - case TextTransitionTypes.ROTATE: - { - return RotationTransition( - child: child, - turns: animation, - ); - } - break; - case TextTransitionTypes.FADE: - { - return FadeTransition( - child: child, - opacity: animation, - ); - } - break; - - case TextTransitionTypes.SIZE: - { - return SizeTransition( - child: child, - sizeFactor: animation, - axisAlignment: widget.value ? -5.0 : 5.0, - axis: Axis.horizontal, - ); - } - break; - - case TextTransitionTypes.SCALE: - { - return ScaleTransition( - child: child, - scale: animation, - ); - } - break; - } - }, - child: Text( - _value ? widget.onText : widget.offText, - key: ValueKey(_value), - style: TextStyle( - color: _value - ? widget.onTextColor - : widget.offTextColor), - ), - ), - ), - ), - ), - ), - ), - ], - ), - )) - ], + ) + ) ), - decoration: BoxDecoration( - border: Border.all( - color: widget.onChanged == null - ? Color(0xFFD3D3D3) - : _value - ? (widget.onBorderColor ?? widget.onThumbColor) - : (widget.offBorderColor ?? widget.offThumbColor), - width: widget.borderSize), - color: _value ? widget.onBkColor : widget.offBkColor, - borderRadius: - BorderRadius.circular(widget.rounded ? 100.0 : 0.0)), - ), + ], ), ); } - - } diff --git a/lib/types/gf_toggle_type.dart b/lib/types/gf_toggle_type.dart index 629c424d..a64cd145 100644 --- a/lib/types/gf_toggle_type.dart +++ b/lib/types/gf_toggle_type.dart @@ -1 +1 @@ -enum GFToggleType { androidSwitch, iosSwitch, labeledSwitch, animatedSwitch, } \ No newline at end of file +enum GFToggleType { android, ios, custom ,square } \ No newline at end of file