diff --git a/example/lib/assets/food.jpeg b/example/lib/assets/food.jpeg new file mode 100644 index 00000000..09f1fcef Binary files /dev/null and b/example/lib/assets/food.jpeg differ diff --git a/example/lib/main.dart b/example/lib/main.dart index a61dfa18..7caed510 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,19 +1,43 @@ -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/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:ui_kit/shape/gf_shape.dart'; +import 'package:ui_kit/components/toggle/gf_toggle.dart'; +import 'package:ui_kit/types/gf_toggle_type.dart'; +import 'package:flutter/cupertino.dart'; + +import 'package:ui_kit/components/toast/gf_toast.dart'; + +final List imageList = [ + "https://cdn.pixabay.com/photo/2017/12/03/18/04/christmas-balls-2995437_960_720.jpg", + "https://cdn.pixabay.com/photo/2017/12/13/00/23/christmas-3015776_960_720.jpg", + "https://cdn.pixabay.com/photo/2019/12/19/10/55/christmas-market-4705877_960_720.jpg", + "https://cdn.pixabay.com/photo/2019/12/20/00/03/road-4707345_960_720.jpg" +]; void main() => runApp(MyApp()); @@ -25,7 +49,12 @@ class MyApp extends StatelessWidget { theme: ThemeData( primarySwatch: Colors.blue, ), - home: MyHomePage(title: 'UI_KIT_EXAMPLE'), +debugShowCheckedModeBanner: false, + +// home: MyHomePage(title: 'UI_KIT_EXAMPLE'), + home: MyHomePage( + title: 'UI KIT', + ), ); } } @@ -40,67 +69,198 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { + bool switchValue = true; @override Widget build(BuildContext context) { + var screenWidth = MediaQuery.of(context).size.width; + var screenHeight = MediaQuery.of(context).size.height; + return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), - body: SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - GFCard( - boxFit: BoxFit.cover, - colorFilter: new ColorFilter.mode( - Colors.black.withOpacity(0.67), BlendMode.darken), - image: Image.asset("lib/assets/pizza.jpeg"), -// imageOverlay: AssetImage("lib/assets/pizza.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, - ), + appBar: AppBar( + title: Text(widget.title), + ), + + body: Column( + children: [ + GFToast( + bgColor: GFColor.warning, + button: GFButton( + onPressed: null, + type: GFType.outline, + text: 'Accept', + ), + text: 'Marked as Favorite.', + ), + Container( + margin: EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + GFToggle( + onChanged: null, + value: null, + type: GFToggleType.android, + duration: Duration(milliseconds: 400), ), - 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), + GFToggle( + onChanged: null, + value: null, + type: GFToggleType.ios, + duration: Duration(milliseconds: 400), ), - 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, - ), - ], + GFToggle( + onChanged: null, + value: null, + type: GFToggleType.custom, + duration: Duration(milliseconds: 400), ), - ), + GFToggle( + onChanged: (val) { + print(val); + }, + value: null, + type: GFToggleType.square, + duration: Duration(milliseconds: 400), + ), + ], + ), + ) + ], + ), + // 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: [ + +// GFSlider( +//// pagerSize: 12.0, +//// activeIndicator: Colors.pink, +//// passiveIndicator: Colors.pink.withOpacity(0.4), +// 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, +// ), +// ), +// ); +// }, +// ).toList(), +// onPageChanged: (index) { +// setState(() { +// index; +// }); +// }, +// ), + +// GFSlider( +// autoPlay: true, +// viewportFraction: 1.0, +// aspectRatio: MediaQuery.of(context).size.aspectRatio, +// 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; +// }); +// }, +// ), + +// 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, @@ -124,97 +284,320 @@ class _MyHomePageState extends State { // ), // ), - 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/pizza.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), - ), +// 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), +//// border: Border.all(color: Colors.pink, width: 2.0), +// ), + + // Card( + // child: Column( + // children: [ + // Text("czsd"), + // Row( + // children: [ + // OutlineButton( + // onPressed: null, + // child: Text("dscds"), + // color: Colors.orange, + // ), + // FlatButton(onPressed: null, child: Text("dchbvj")) + // ], + // ) + // ], + // ), + // ), + + // 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( + // avatar: GFAvatar( + // child: Text("tb"), + // ), + // title: Text('title'), + // subTitle: Text('subtitle'), + // icon: GFIconButton( + // type: GFType.transparent, + // icon: Icon(Icons.favorite_border), + // ), + // ), + +// GFCard( + +// headertype: GFAtb(), + +// po + +// image + +// overlaytext + +// content: Text("content"), + +// buttonbar: gfbb() -// -// GFAvatar( -//// radius: 40.0, -// child: Text("de"), -// backgroundColor: Colors.pink, -//// backgroundImage: , -//// foregroundColor: Colors.deepOrangeAccent, -//// shape: GFShape.square, -//// size: GFSize.medium, -//// borderRadius: BorderRadius.circular(20.0), // ), -// GFIconBadges( -// onPressed: null, -// child: GFIconButton( -// onPressed: null, -// icon: Icon(Icons.ac_unit), + +// + +// gfbb( + +// children[ + +// + +// ] + +// ) + +// GFimageoverlay() + +// GFAvatar( +// // radius: 20.0, +// maxRadius: 50, + +// child: Text("de"), + +// backgroundColor: Colors.pink, + +// backgroundImage: , + +// foregroundColor: Colors.deepOrangeAccent, + + // shape: GFShape.square, + +// size: GFSize.medium, + +// borderRadius: BorderRadius.circular(20.0), + // ), + + // GFIconBadges( + // onPressed: null, + // child: GFIconButton( + // onPressed: null, + // icon: Icon(Icons.ac_unit), + // ), + // 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), + // ), + // ), + + // GFIconButton( + // onPressed: null, + + // icon: Icon(Icons.ac_unit), + +// iconSize: 12.0, + +// type: GFType.solid, + +// shape: GFShape.pills, + +// size: GFSize.large, + +// buttonBoxShadow: true, + +// color: GFColor.primary, + +// boxShadow: BoxShadow( + +// color: Colors.pink, + +// blurRadius: 2.0, + +// spreadRadius: 1.0, + +// offset: Offset.zero, + // ), -// 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), + +// 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), + // ), + +// GFButtonBadge( +// onPressed: null, + +// // position: GFIconPosition.start, + +// // 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), + +// text: 'goodies', + +// // color: GFColor.danger, + +// // shape: GFShape.pills, + +// // type: GFType.outline, + +// // size: GFSize.small, + +// 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', + +// // 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), +// ), + +// GFButton( +// // type: GFType.solid, + +// // shape: GFShape.pills, + +// text: 'goodies', + +// onPressed: () {}, + +// textStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: 8.0), + +// size: GFSize.large, + +// buttonBoxShadow: true, + +// blockButton: true, + +// fullWidthButton: true, + +// color: GFColor.primary, + +// textColor: GFColor.secondary, + +// icon: Icon(Icons.error, color: Colors.white,), + +// position: GFIconPosition.start, + +// boxShadow: BoxShadow( + +// color: Colors.pink, + +// blurRadius: 2.0, + +// spreadRadius: 1.0, + +// offset: Offset.zero, + // ), // ), // GFIconButton( @@ -287,8 +670,10 @@ 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/example/pubspec.yaml b/example/pubspec.yaml index 95eca7a1..4ebcc8a4 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,4 +1,4 @@ -name: ui_kit_example +name: example description: A new Flutter project. version: 1.0.0+1 @@ -19,4 +19,6 @@ dev_dependencies: sdk: flutter flutter: - uses-material-design: true \ No newline at end of file + uses-material-design: true + assets: + - lib/assets/food.jpeg \ No newline at end of file diff --git a/lib/colors/gf_color.dart b/lib/colors/gf_color.dart index 0175c29f..002b98d5 100644 --- a/lib/colors/gf_color.dart +++ b/lib/colors/gf_color.dart @@ -12,19 +12,21 @@ 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 +67,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/header/gf_header.dart b/lib/components/header/gf_header.dart new file mode 100644 index 00000000..e69de29b diff --git a/lib/components/slider/gf_slider.dart b/lib/components/slider/gf_slider.dart new file mode 100644 index 00000000..ce04c443 --- /dev/null +++ b/lib/components/slider/gf_slider.dart @@ -0,0 +1,314 @@ +import 'dart:async'; +import 'dart:ffi'; +import 'package:flutter/material.dart'; + +List map(List list, Function handler) { + List result = []; + for (var i = 0; i < list.length; i++) { + result.add(handler(i, list[i])); + } + return result; +} + +class GFSlider extends StatefulWidget { + GFSlider( + {@required this.items, + this.pagerSize, + this.passiveIndicator, + this.activeIndicator, + this.pagination, + this.height, + this.aspectRatio: 16 / 9, + this.viewportFraction: 0.8, + this.initialPage: 0, + int realPage: 10000, + this.enableInfiniteScroll: true, + this.reverse: false, + this.autoPlay: false, + this.autoPlayInterval: const Duration(seconds: 4), + this.autoPlayAnimationDuration = const Duration(milliseconds: 800), + this.autoPlayCurve: Curves.fastOutSlowIn, + this.pauseAutoPlayOnTouch, + this.enlargeMainPage = false, + this.onPageChanged, + this.scrollPhysics, + this.scrollDirection: Axis.horizontal}) + : this.realPage = enableInfiniteScroll ? realPage + initialPage : initialPage, + this.pageController = PageController( + viewportFraction: viewportFraction, + initialPage: enableInfiniteScroll ? realPage + initialPage : initialPage, + ); + + /// The pagination dots size can be defined using [double]. + final double pagerSize; + + /// The slider pagination's active color. + final Color activeIndicator; + + /// The slider pagination's passive color. + final Color passiveIndicator; + + /// The [GFSlider] shows pagination on state true. + final bool pagination; + + /// The widgets to be shown as sliders. + final List items; + + /// Set slide widget height and overrides any existing [aspectRatio]. + final double height; + + /// Aspect ratio is used if no height have been declared. Defaults to 16:9 aspect ratio. + final double aspectRatio; + + /// The fraction of the viewport that each page should occupy. Defaults to 0.8, which means each page fills 80% of the slide. + final num viewportFraction; + + /// The initial page to show when first creating the [GFSlider]. Defaults to 0. + final num initialPage; + + /// The actual index of the [PageView]. + final num realPage; + + /// Determines if slides should loop infinitely or be limited to item length. Defaults to true, i.e. infinite loop. + final bool enableInfiniteScroll; + + /// Reverse the order of items if set to true. Defaults to false. + final bool reverse; + + /// Enables auto play, sliding one page at a time. Use [autoPlayInterval] to determent the frequency of slides. Defaults to false. + final bool autoPlay; + + /// Sets Duration to determent the frequency of slides when [autoPlay] is set to true. Defaults to 4 seconds. + final Duration autoPlayInterval; + + /// The animation duration between two transitioning pages while in auto playback. Defaults to 800 ms. + final Duration autoPlayAnimationDuration; + + /// Determines the animation curve physics. Defaults to [Curves.fastOutSlowIn]. + final Curve autoPlayCurve; + + /// Sets a timer on touch detected that pause the auto play with the given [Duration]. Touch Detection is only active if [autoPlay] is true. + final Duration pauseAutoPlayOnTouch; + + /// Determines if current page should be larger then the side images, + /// creating a feeling of depth in the carousel. Defaults to false. + final bool enlargeMainPage; + + /// The axis along which the page view scrolls. Defaults to [Axis.horizontal]. + final Axis scrollDirection; + + /// Called whenever the page in the center of the viewport changes. + final Function(int index) onPageChanged; + + /// How the carousel should respond to user input. + /// + /// For example, determines how the items continues to animate after the + /// user stops dragging the page view. + /// + /// The physics are modified to snap to page boundaries using + /// [PageScrollPhysics] prior to being used. + /// + /// Defaults to matching platform conventions. + final ScrollPhysics scrollPhysics; + + /// [pageController] is created using the properties passed to the constructor + /// and can be used to control the [PageView] it is passed to. + final PageController pageController; + + /// Animates the controlled [GFSlider] to the next page. + /// + /// The animation lasts for the given duration and follows the given curve. + /// The returned [Future] resolves when the animation completes. + Future nextPage({Duration duration, Curve curve}) { + return pageController.nextPage(duration: duration, curve: curve); + } + + /// Animates the controlled [GFSlider] to the previous page. + /// + /// The animation lasts for the given duration and follows the given curve. + /// The returned [Future] resolves when the animation completes. + Future previousPage({Duration duration, Curve curve}) { + return pageController.previousPage(duration: duration, curve: curve); + } + + /// Changes which page is displayed in the controlled [GFSlider]. + /// + /// Jumps the page position from its current value to the given value, + /// without animation, and without checking if the new value is in range. + void jumpToPage(int page) { + final index = _getRealIndex(pageController.page.toInt(), realPage, items.length); + return pageController.jumpToPage(pageController.page.toInt() + page - index); + } + + /// Animates the controlled [GFSlider] from the current page to the given page. + /// + /// The animation lasts for the given duration and follows the given curve. + /// The returned [Future] resolves when the animation completes. + Future animateToPage(int page, {Duration duration, Curve curve}) { + final index = _getRealIndex(pageController.page.toInt(), realPage, items.length); + return pageController.animateToPage(pageController.page.toInt() + page - index, + duration: duration, curve: curve); + } + + @override + _GFSliderState createState() => _GFSliderState(); +} + +class _GFSliderState extends State with TickerProviderStateMixin { + Timer timer; + + @override + void initState() { + super.initState(); + timer = getPlayTimer(); + } + + Timer getPlayTimer() { + return Timer.periodic(widget.autoPlayInterval, (_) { + if (widget.autoPlay) { + widget.pageController + .nextPage(duration: widget.autoPlayAnimationDuration, curve: widget.autoPlayCurve); + } + }); + } + + void pauseOnTouch() { + timer.cancel(); + timer = Timer(widget.pauseAutoPlayOnTouch, () { + timer = getPlayTimer(); + }); + } + + Widget getPageWrapper(Widget child) { + if (widget.height != null) { + final Widget wrapper = Container(height: widget.height, child: child); + return widget.autoPlay && widget.pauseAutoPlayOnTouch != null + ? addGestureDetection(wrapper) + : wrapper; + } else { + final Widget wrapper = AspectRatio(aspectRatio: widget.aspectRatio, child: child); + return widget.autoPlay && widget.pauseAutoPlayOnTouch != null + ? addGestureDetection(wrapper) + : wrapper; + } + } + + Widget addGestureDetection(Widget child) => + GestureDetector(onPanDown: (_) => pauseOnTouch(), child: child); + + @override + void dispose() { + super.dispose(); + timer?.cancel(); + } + + int _current = 0; + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + getPageWrapper(PageView.builder( + physics: widget.scrollPhysics, + scrollDirection: widget.scrollDirection, + controller: widget.pageController, + reverse: widget.reverse, + itemCount: widget.enableInfiniteScroll ? null : widget.items.length, + onPageChanged: (int index) { + + int currentPage = _getRealIndex(index + widget.initialPage, widget.realPage, widget.items.length); + if (widget.onPageChanged != null) { + widget.onPageChanged(currentPage); + _current = currentPage; + } + _current = currentPage; + }, + itemBuilder: (BuildContext context, int i) { + final int index = + _getRealIndex(i + widget.initialPage, widget.realPage, widget.items.length); + + return AnimatedBuilder( + animation: widget.pageController, + child: widget.items[index], + builder: (BuildContext context, child) { + // on the first render, the pageController.page is null, + // this is a dirty hack + if (widget.pageController.position.minScrollExtent == null || + widget.pageController.position.maxScrollExtent == null) { + Future.delayed(Duration(microseconds: 1), () { + setState(() {}); + }); + return Container(); + } + double value = widget.pageController.page - i; + value = (1 - (value.abs() * 0.3)).clamp(0.0, 1.0); + + final double height = + widget.height ?? MediaQuery.of(context).size.width * (1 / widget.aspectRatio); + final double distortionValue = + widget.enlargeMainPage ? Curves.easeOut.transform(value) : 1.0; + + if (widget.scrollDirection == Axis.horizontal) { + return Center(child: SizedBox(height: distortionValue * height, child: child)); + } else { + return Center( + child: SizedBox( + width: distortionValue * MediaQuery.of(context).size.width, child: child)); + } + }, + ); + }, + )), + widget.pagination == true ? Positioned( + left: 0.0, + right: 0.0, + bottom: 0.0, + child: Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: map( + widget.items, + (indexx, url) { + return Container( + width: widget.pagerSize == null ? 8.0 : widget.pagerSize, + height: widget.pagerSize == null ? 8.0 : widget.pagerSize, + margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: _current == indexx + ? widget.activeIndicator == null ? Color.fromRGBO(0, 0, 0, 0.9) : widget.activeIndicator + : widget.passiveIndicator == null ? Color.fromRGBO(0, 0, 0, 0.4) : widget.passiveIndicator, + ), + ); + }, + ), + ), + ), + ) : Container(), + ], + ); + } +} + +/// Converts an index of a set size to the corresponding index of a collection of another size +/// as if they were circular. +/// +/// Takes a [position] from collection Foo, a [base] from where Foo's index originated +/// and the [length] of a second collection Baa, for which the correlating index is sought. +/// +/// For example; We have a Carousel of 10000(simulating infinity) but only 6 images. +/// We need to repeat the images to give the illusion of a never ending stream. +/// By calling _getRealIndex with position and base we get an offset. +/// This offset modulo our length, 6, will return a number between 0 and 5, which represent the image +/// to be placed in the given position. +int _getRealIndex(int position, int base, int length) { + final int offset = position - base; + return _remainder(offset, length); +} + +/// Returns the remainder of the modulo operation [input] % [source], and adjust it for +/// negative values. +int _remainder(int input, int source) { + final int result = input % source; + return result < 0 ? source + result : result; +} \ No newline at end of file diff --git a/lib/components/tabs/gf_tabs.dart b/lib/components/tabs/gf_tabs.dart new file mode 100644 index 00000000..e69de29b diff --git a/lib/components/toast/gf_toast.dart b/lib/components/toast/gf_toast.dart new file mode 100644 index 00000000..b8656bb3 --- /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.bgColor, + this.text, + this.textStyle = const TextStyle(color: Colors.white70, height: 1.5), + }) :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 bgColor; + + /// 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: bgColor!=null ?getGFColor(bgColor):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 167c2619..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