diff --git a/example/lib/main.dart b/example/lib/main.dart index cc029e6a..7b616839 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -14,7 +14,6 @@ class MyApp extends StatelessWidget { ); } -// class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); diff --git a/example/lib/main_temp.dart b/example/lib/main_temp.dart index c756d5cb..62e2f4bf 100644 --- a/example/lib/main_temp.dart +++ b/example/lib/main_temp.dart @@ -1,3 +1,4 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:getwidget/getwidget.dart'; @@ -18,13 +19,13 @@ void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) => MaterialApp( - title: 'GetWidget Example', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - debugShowCheckedModeBanner: false, - home: const MyHomePage(title: 'GetWidget Example'), - ); + title: 'GetWidget Example', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + debugShowCheckedModeBanner: false, + home: const MyHomePage(title: 'GetWidget Example'), + ); } class MyHomePage extends StatefulWidget { @@ -38,9 +39,15 @@ class MyHomePage extends StatefulWidget { class _MyHomePageState extends State with SingleTickerProviderStateMixin { + final _scaffoldKey = new GlobalKey(); TabController tabController; final _ratingController = TextEditingController(); bool check = false; + String searchData; + final TextEditingController _searchController = TextEditingController(); + int groupValue = 0; + final GFBottomSheetController _controller = GFBottomSheetController(); + double foo = 100.0; @override void initState() { @@ -69,1754 +76,127 @@ class _MyHomePageState extends State 'Xamarin2', ]; - @override - Widget build(BuildContext context) => - // final Widget emptyBlock = Padding( - // padding: const EdgeInsets.symmetric(horizontal: 16), - // child: Row( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // Container( - // width: 54, - // height: 46, - // color: Colors.white, - // ), - // const SizedBox(width: 12), - // Expanded( - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // Container( - // width: double.infinity, - // height: 8, - // color: Colors.white, - // ), - // const SizedBox(height: 6), - // Container( - // width: MediaQuery.of(context).size.width * 0.5, - // height: 8, - // color: Colors.white, - // ), - // const SizedBox(height: 6), - // Container( - // width: MediaQuery.of(context).size.width * 0.25, - // height: 8, - // color: Colors.white, - // ), - // ], - // ), - // ) - // ], - // ), - // ); + void _persistentBottomSheet() { + _scaffoldKey.currentState.showBottomSheet((context) => Container( + color: Colors.redAccent, + height: 250, + child: const Center( + child: Text('Hey! guys , this is a persistent bottom sheet'), + ), + )); + } - Scaffold( - drawer: GFDrawer( -// colorFilter: new ColorFilter.mode( -// Colors.teal.withOpacity(0.6), BlendMode.DARKen), -// backgroundImage: NetworkImage( -// "https://cdn.pixabay.com/photo/2017/12/03/18/04/christmas-balls-2995437_960_720.jpg"), - gradient: LinearGradient( - begin: Alignment.topRight, - end: Alignment.bottomLeft, - stops: const [0.1, 0.5, 0.7, 0.9], - colors: [ - Colors.teal[800], - Colors.teal[600], - Colors.teal[400], - Colors.teal[200], - ], + void _modalBottomSheetMenu() { + showModalBottomSheet( + context: context, + elevation: 10, + builder: (builder) => Container( + height: 350, + color: Colors.transparent, + child: Container( + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(10), + topRight: Radius.circular(10))), + child: const Center( + child: Text('This is a modal sheet'), + )), + )); + } + + @override + Widget build(BuildContext context) => Scaffold( + key: _scaffoldKey, + appBar: GFAppBar( + backgroundColor: Colors.blueGrey, + title: const Text('UI Kit'), + centerTitle: true, + ), + body: SingleChildScrollView( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + height: 10, + ), + Radio( + value: 0, + groupValue: groupValue, + onChanged: (val) { + setState(() { + groupValue = val; + }); + }, ), - color: Colors.greenAccent, - child: ListView( - padding: EdgeInsets.zero, - children: [ - GFDrawerHeader( - currentAccountPicture: const GFAvatar( - radius: 80, - backgroundImage: NetworkImage( - 'https://cdn.pixabay.com/photo/2017/12/03/18/04/christmas-balls-2995437_960_720.jpg'), - ), - decoration: BoxDecoration( - color: Colors.teal, - ), - otherAccountsPictures: const [ - Image( - image: NetworkImage( - 'https://cdn.pixabay.com/photo/2019/12/20/00/03/road-4707345_960_720.jpg'), - fit: BoxFit.cover, - ), - GFAvatar( - child: Text('dcf'), - ) - ], -// closeButton: Text("Close"), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: const [ - Text('user name'), - Text('user@userid.com'), - ], - ), - ), - const ListTile( - title: Text('Item 1'), - onTap: null, - ), - const ListTile( - title: Text('Item 2'), - onTap: null, - ), - ], + Radio( + value: 1, + groupValue: groupValue, + onChanged: (val) { + setState(() { + groupValue = val; + }); + }, ), +// Expanded(child: SizedBox.expand( +// child: DraggableScrollableSheet( +// builder: (BuildContext context, ScrollController scrollController) => Container( +// color: Colors.blue[100], +// child: ListView.builder( +// controller: scrollController, +// itemCount: 25, +// itemBuilder: (BuildContext context, int index) => ListTile(title: Text('Item $index')), +// ), +// ), +// ), +// ),) + ], + ), + ), + bottomSheet: GFBottomSheet( + controller: _controller, +// minContentHeight: 100, + maxContentHeight: 500, +// elevation: 10, + stickyHeader: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.tealAccent), + height: 50, + child: const Center( + child: Text('Swipe me!'), ), - - appBar: GFAppBar( - backgroundColor: Colors.teal, -// centerTitle: true, -// leading: GFIconButton(icon: Icon(Icons.directions_bus), onPressed: (){}), - title: const Text('UI Kit'), -// GFSegmentTabs( -// tabController: tabController, -// initialIndex: 0, -// length: 3, -// tabs: const [ -// Text( -// 'Tab1', -// ), -// Text( -// 'Tab2', -// ), -// Text( -// 'Tab3', -// ), -// ], -// ), -// bottom: TabBar( -// controller: tabController, -// tabs: const [ -// Text( -// 'Tab1', -// ), -// Text( -// 'Tab1', -// ), -// Text( -// 'Tab1', -// ), -// ], -// labelStyle: TextStyle( -// fontWeight: FontWeight.w900, -// fontSize: 19, -// color: Colors.deepOrange, -// fontFamily: 'OpenSansBold', -// ), -// unselectedLabelStyle: TextStyle( -// fontWeight: FontWeight.w500, -// fontSize: 13, -// color: Colors.black, -// fontFamily: 'OpenSansBold', -// ), -// ), - searchBar: true, -// searchHintText: "aaaaaaa", -// searchHintStyle: TextStyle(fontSize: 18.0, color: Colors.redAccent), -// searchStyle: TextStyle(fontSize: 10.0, color: Colors.green), -// searchBarColorTheme: Colors.greenAccent, - - actions: [ -// GFIconButton(icon: Icon(Icons.access_time), onPressed: () {}), - GFIconButton( - icon: Icon( - Icons.favorite, - color: GFColors.WHITE, - ), - onPressed: () {}, - type: GFButtonType.transparent, - ), + ), + contentBody: Container( + child: ListView( + children: const [ + Text('fhj'), + Text('fhj'), + Text('fhj'), + Text('fhj'), + Text('fhj'), + Text('fhj'), ], ), -// backgroundColor: Colors.blueGrey, - body: -// GFTabBarView( -// height: 200.0, -// controller: tabController, -// children: [ -// Container(color: Colors.red,), -// Container(color: Colors.green), -// Container(color: Colors.blue) -// ]), -// DefaultTabController( -// length: 9, -// child: Scaffold( -// appBar: AppBar( -// bottom: TabBar( -// isScrollable: true, -// tabs: [ -// Tab(icon: Icon(Icons.directions_car)), -// Tab(icon: Icon(Icons.directions_transit)), -// Tab(icon: Icon(Icons.directions_bike)), -// Tab(icon: Icon(Icons.directions_car)), -// Tab(icon: Icon(Icons.directions_transit)), -// Tab(icon: Icon(Icons.directions_bike)), -// 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), -// Icon(Icons.directions_car), -// Icon(Icons.directions_transit), -// Icon(Icons.directions_bike), -// Icon(Icons.directions_car), -// Icon(Icons.directions_transit), -// Icon(Icons.directions_bike), -// ], -// ), -// ), -// ) -// ); - SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ -// GFAccordion( -// titleChild: Text('fgk'), -// contentChild: Text('hhjk'), -//// title: 'GF Accordion', -//// content: 'GetWidget is an open source library that comes with pre-build 1000+ UI components.', -// collapsedIcon: Text('Show'), -// expandedIcon: Text('Hide') -// ), - -// GFFloatingWidget( -// child: GFToast( -// text: 'This item already has the label “travel”', -// autoDismiss: true, -// ), -// body: Container( -// color: Colors.blueAccent, -// child: Text('body or any kind of widget here..'), -// )), - -// GFRating( -// value: _rating, -// color: GFColors.DANGER, -// borderColor: GFColors.WARNING, -// onChanged: (value) { -// setState(() { -// _rating = value; -// }); -// }, -// ), - -// GFShimmer( -// child: const Text( -// 'GF Shimmer', -// style: TextStyle(fontSize: 48, fontWeight: FontWeight.w700), -// ), -// showGradient: true, -// gradient: LinearGradient( -// begin: Alignment.bottomRight, -// end: Alignment.centerLeft, -// stops: const [0, 0.3, 0.6, 0.9, 1], -// colors: [ -// Colors.teal[100], -// Colors.teal[200], -// Colors.teal[300], -// Colors.teal[400], -// Colors.teal[500], -// ], -// ), -// ), - -// GFShimmer( -// child: emptyBlock, -//// mainColor: GFColors.DARK, -//// secondaryColor: GFColors.LIGHT, -//// direction: GFShimmerDirection.rightToLeft, -//// duration: const Duration(milliseconds: 1200), -//// shimmerEffectCount: 3, -//// showShimmerEffect: false, -// ), - -// GFRating( -// value: _rating, -//// size: 50, -// filledIcon: Icon( -// Icons.done_outline, -// size: 40, -// color: Colors.teal, -// ), -// halfFilledIcon: Icon( -// Icons.done_all, -// size: 40, -// color: Colors.teal.withOpacity(0.75), -// ), -// defaultIcon: Icon( -// Icons.done, -// size: 40, -// color: Colors.teal.withOpacity(0.25), -// ), -//// spacing: 8, -//// color: Colors.teal, -//// borderColor: Colors.tealAccent, -//// allowHalfRating: false, -// onChanged: (value) { -// setState(() { -// _rating = value; -// print('user selected $_rating'); -// }); -// }, -// ), -// -// GFRating( -// value: _rating, -// size: GFSize.large, -// filledIcon: Icon( -// Icons.sentiment_very_satisfied, -// color: Colors.green, -// size: 50, -// ), -// halfFilledIcon: Icon( -// Icons.sentiment_neutral, -// color: Colors.amber, -// size: 50, -// ), -// defaultIcon: Icon( -// Icons.sentiment_very_dissatisfied, -// color: Colors.red, -// size: 50, -// ), -// onChanged: (value) { -// setState(() { -// _rating = value; -// print('user selected $_rating'); -// }); -// }, -// ), - -// GFRating( -// value: _userRating, -//// filledIcon: Image.asset( -//// 'lib/assets/heart.png', -//// height: 50, -//// width: 50, -//// color: Colors.amber, -//// ), -//// halfFilledIcon: Image.asset( -//// 'lib/assets/heart_half.png', -//// height: 50, -//// width: 50, -//// color: Colors.amber, -//// ), -//// defaultIcon: Image.asset( -//// 'lib/assets/heart_border.png', -//// height: 50, -//// width: 50, -//// color: Colors.amber, -//// ), -//// spacing: 8, -// controller: _ratingController, -// showTextForm: true, -// suffixIcon: GFButton( -// type: GFButtonType.transparent, -// onPressed: () { -// setState(() { -// _userRating = double.parse(_ratingController.text ?? '0.0'); -// }); -// }, -// child: const Text('Rate'), -// ), -// ), - -// GFSearchBar( -//// searchBoxInputDecoration: InputDecoration( -//// enabledBorder: OutlineInputBorder( -//// borderSide: BorderSide( -//// color: Colors.teal, -//// ), -//// borderRadius: BorderRadius.circular(50) -//// ), -//// ), -// searchList: list, -//// hideSearchBoxWhenItemSelected: false, -//// overlaySearchListHeight: 100.0, -// searchQueryBuilder: (query, list) => list -// .where((item) => -// item.toLowerCase().contains(query.toLowerCase())) -// .toList(), -// overlaySearchListItemBuilder: (item) => Container( -// padding: const EdgeInsets.all(8), -// child: Text( -// item, -// style: const TextStyle(fontSize: 18), -// ), -// ), -//// noItemsFoundWidget: Container( -//// color: Colors.green, -//// child: Text("no items found..."), -//// ), -// onItemSelected: (item) { -// setState(() { -// print('selected item $item'); -// }); -// }), - -// GFCard( -// content: Column( -// children: [ -// const GFTypography( -// text: 'Toast', -// type: GFTypographyType.typo6, -// ), -// const SizedBox( -// height: 20, -// ), -// const SizedBox( -// height: 20, -// ), -// GFToast( -// text: 'Happy New Year', -// button: GFButton( -// onPressed: () { -// print('dfr'); -// }, -// text: 'OK', -// type: GFButtonType.outline, -// color: GFColors.WARNING, -// ), -// ), -// ], -// ), -// ), -// -// GFCard( -// content: Column( -// children: [ -// GFTypography( -// text: 'Floating Toast', -// type: GFTypographyType.typo6, -// ), -// GFFloatingWidget( -// verticalPosition: 100, -// child: showToast -// ? GFToast( -// width: 300, -// text: 'Happy New Year', -// button: GFButton( -// onPressed: () { -// print("df"); -// }, -// text: 'OK', -// type: GFButtonType.outline, -// color: GFColors.WARNING, -// ), -// ) -// : Container(), -// body: Column( -// crossAxisAlignment: CrossAxisAlignment.center, -// children: [ -// Container( -// alignment: Alignment.center, -// child: GFButton( -// onPressed: () { -// setState(() { -// showToast = !showToast; -// }); -// }, -// text: 'Click to View the toast', -// type: GFButtonType.outline, -// color: GFColors.WARNING, -// ), -// ) -// ], -// )) -// ], -// ), -// ), - -// Container( -// height: 130, -// width: 105, -// decoration: BoxDecoration( -// borderRadius: BorderRadius.circular(8), -// gradient: LinearGradient( -// begin: FractionalOffset.bottomLeft, -// end: FractionalOffset.topRight, -// colors: const [ -// Color(0x5a0b486b), -// Color(0xFFF56217), -// ]), -// ), -// ), - -// GFCard( -// content: Column( -// children: [ -// GFTypography( -// text: 'IOS', -// type: GFTypographyType.typo6, -// ), -// SizedBox( -// height: 10, -// ), -// GFToggle( -// onChanged: null, -// value: null, -// type: GFToggleType.ios, -// ) -// ], -// ), -// ), - -// GFCard( -// content: Container( -// height: 300.0, -// child: new Stack( //if fit not specified then, it aligns to top left.... -// fit: StackFit.expand, -// children: [ -// Column( -// children: [ -// GFTypography( -// text: 'GF Header Typo1', -// type: GFTypographyType.typo1, -//// showDivider: false, -// ), -// GFTypography( -// text: 'GF Header Typo2', -// type: GFTypographyType.typo2, -// showDivider: false, -// ), -// GFTypography( -// text: 'GF Header Typo3', -// type: GFTypographyType.typo3, -// showDivider: false, -// ), -// GFTypography( -// text: 'GF Header Typo4', -// type: GFTypographyType.typo4, -// showDivider: false, -// ), -// GFTypography( -// text: 'GF Header Typo5', -// type: GFTypographyType.typo5, -// showDivider: false, -// ), -// GFTypography( -// text: 'GF Header Typo6', -// type: GFTypographyType.typo6, -// showDivider: false, -// ), -// ], -// ), -// new DecoratedBox( -// decoration: new BoxDecoration( -// //color: Colors.lightGreen -// gradient: new LinearGradient( -// begin: FractionalOffset.bottomLeft, -// end: FractionalOffset.topRight, -// colors: [ -// const Color(0x5a0b486b), -// const Color(0xFFF56217), -// ] -// ) -// ), -// ), -// ], -// ), -// ), -// ), - -// GFButtonBar( -// alignment: WrapAlignment.spaceEvenly, -// children: [ -// GFButton( -// onPressed: null, -// child: Text("dshsc"), -// icon: Icon(Icons.access_time), -// ), -// GFButton( -// onPressed: null, -// child: Text("dszndc"), -// icon: Icon(Icons.WARNING), -// ), - GFButtonBadge( - onPressed: null, - text: 'test button', - icon: Icon(Icons.label), - ), -// GFButton( -// onPressed: null, -// child: Text("gcnjd"), -// ), -// GFButton( -// onPressed: null, -// child: Text("dsqdsc"), -// icon: Icon(Icons.favorite), -// ), -// GFButton( -// onPressed: null, -// child: Text("gcd"), -// ), -// GFButton( -// onPressed: null, -// child: Text("dascdsc"), -// ), -// GFButton( -// onPressed: null, -// child: Text("gtgcd"), -// ), -// ], -// ), - -// GFCard( -// content: Column( -// crossAxisAlignment: CrossAxisAlignment.center, -// mainAxisAlignment: MainAxisAlignment.spaceBetween, -// children: [ -// GFTypography( -// text: 'GF Header Typo1', -// type: GFTypographyType.typo1, -// backgroundImage: NetworkImage( -// 'https://cdn.pixabay.com/photo/2019/12/25/16/49/happy-new-year-4718894_960_720.png'), -// ), -// SizedBox( -// height: 40, -// ), -// GFTypography( -// icon: GFAvatar(), -// text: 'GF Header Typo2', -// type: GFTypographyType.typo2, -// dividerColor: GFColors.PRIMARY, -// dividerAlignment: Alignment.center, -// ), -// SizedBox( -// height: 40, -// ), -// GFTypography( -// icon: Icon(Icons.insert_emoticon), -// text: 'GF Header Typo3', -// type: GFTypographyType.typo3, -// dividerWidth: 150, -// dividerColor: GFColors.WARNING, -// dividerBorderRadius: BorderRadius.all(Radius.circular(0)), -// ), -// SizedBox( -// height: 40, -// ), -// GFTypography( -// text: 'GF Header Typo4', -// type: GFTypographyType.typo4, -// dividerWidth: 345, -// icon: Image.network( -// 'https://cdn.pixabay.com/photo/2016/12/15/03/27/cocoa-1908020_960_720.jpg', -// width: 50, -// )), -// SizedBox( -// height: 40, -// ), -// GFTypography( -// text: 'GF Header Typo5', -// type: GFTypographyType.typo5, -// dividerColor: GFColors.ALT, -// ), -// SizedBox( -// height: 40, -// ), -// GFTypography( -// text: 'GF Header Typo6', -// type: GFTypographyType.typo6, -// dividerWidth: 20, -// ), -// ], -// ) -// ), - -// GFButton( -// type: GFButtonType.transparent, -// color: GFColors.WARNING, -// onPressed: () {}, -// text: 'whatsapp', -// icon: Icon(Icons.directions_bike), -// ), -// -// GFButton( -// text: "linkedin", -// icon: Icon(Icons.directions_bike), -// ), - - GFListTile( -// padding: EdgeInsets.all(30.0), -// margin: EdgeInsets.all(50.0), - color: Colors.blueGrey, -// avatar: const GFAvatar( -// child: Text('tb'), -// ), - title: const Text('title'), -// subTitle: const Text('subtitle'), -// description: -// const Text('A page view that displays the widget which '), - icon: const Icon(Icons.category), -// dividerColor: Colors.blue, -// dividerEndIndent: 20.0, -// dividerHeight: 2.0, -// dividerIndent: 30.0, -// dividerThickness: 5.0, -// showDivider: false, - ), - -// GFCard( -// title: GFListTile( -// avatar: GFAvatar( -// shape: GFAvatarShape.standard, -// ), -// title: GFTypography( -// text: 'List tile', -// type: GFTypographyType.typo5, -// showDivider: false, -// ), -// subTitle: Text( -// 'Lorem ipsum', -// style: TextStyle(color: getGFColors(GFColors.DARK)), -// ), -// description: Text( -// 'Dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ' -// 'sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ', -// style: TextStyle( -// fontSize: 13, color: getGFColors(GFColors.SECONDARY))), -// showDivider: false, -// icon: GFIconButton( -// onPressed: null, -// type: GFButtonType.transparent, -// icon: Icon(Icons.favorite_border), -// ), -// ), -// ), -// -// GFCard( -// content: GFListTile( -// avatar: GFAvatar( -// shape: GFAvatarShape.standard, -// ), -// title: GFTypography( -// text: 'List tile', -// type: GFTypographyType.typo5, -// showDivider: false, -// ), -// subTitle: Text( -// 'Lorem ipsum', -// style: TextStyle(color: getGFColors(GFColors.DARK)), -// ), -// description: Text( -// 'Dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ', -// style: TextStyle( -// fontSize: 13, color: getGFColors(GFColors.SECONDARY))), -// showDivider: false, -// ), -// ), -// -// GFCard( -// content: Row( -// children: [ -// GFImageOverlay( -// height: 200.0, -// width: 304.0, -// image: AssetImage("lib/assets/food.jpeg"), -// boxFit: BoxFit.cover, -// colorFilter: new ColorFilter.mode( -// Colors.black.withOpacity(0.67), BlendMode.DARKen), -//// shape: BoxShape.circle, -// ), -// ], -// )), - - // Image.asset( - // 'lib/assets/food.jpeg', - // fit: BoxFit.cover, - // color: Color(0xff0d69ff).withOpacity(1.0), - // colorBlendMode: BlendMode.softLight, - // ), - -// GFCard( -// content: Container( -// width: 190.0, -// height: 190.0, -// decoration: new BoxDecoration( -// shape: BoxShape.circle, -// image: new DecorationImage( -// fit: BoxFit.fill, -// image: AssetImage( -// "lib/assets/food.jpeg", -// ), -// ))), -// ), - - GFButtonBadge( -// boxShadow: BoxShadow( -// color: Colors.pink, -// blurRadius: 2.0, -// spreadRadius: 1.0, -// offset: Offset.zero, -// ), -// badgeBoxShadow: true, - onPressed: () {}, -// position: GFPosition.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: 'goodiesdxs', -// color: GFColors.success, - textColor: GFColors.DARK, - shape: GFButtonShape.pills, - type: GFButtonType.outline2x, -// size: GFSize.small, - icon: const GFBadge( - child: Text('12'), -// color: GFColors.DARK, -// shape: GFBadgeShape.circle, -// size: GFSize.small, -// border: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid), -// borderShape: RoundedRectangleBorder(), -// textColor: GFColors.WHITE, -// textStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: 8.0), - ), - ), - -// TabBar( -// isScrollable: true, -// labelColor: GFColors.PRIMARY, -// controller: tabController, -// tabs: [ -// Tab( -// icon: Icon(Icons.directions_bike), -// child: Text( -// "Tab1", -// ), -// ), -// Tab( -// icon: Icon(Icons.directions_bus), -// child: Text( -// "Tab2", -// ), -// ), -// Tab( -// icon: Icon(Icons.directions_railway), -// child: Text( -// "Tab3", -// ), -// ), -// Tab( -// icon: Icon(Icons.directions_bike), -// child: Text( -// "Tab1", -// ), -// ), -// Tab( -// icon: Icon(Icons.directions_bus), -// child: Text( -// "Tab2", -// ), -// ), -// Tab( -// icon: Icon(Icons.directions_railway), -// child: Text( -// "Tab3", -// ), -// ), -// ], -// ), -// -// -// GFTabs( -// initialIndex: 4, -// isScrollable: true, -// length: 6, -// tabs: [ -// Tab( -// icon: Icon(Icons.directions_bike), -// child: Text( -// "Tab1", -// ), -// ), -// Tab( -// icon: Icon(Icons.directions_bus), -// child: Text( -// "Tab2", -// ), -// ), -// Tab( -// icon: Icon(Icons.directions_railway), -// child: Text( -// "Tab3", -// ), -// ), -// Tab( -// icon: Icon(Icons.directions_bike), -// child: Text( -// "Tab1", -// ), -// ), -// Tab( -// icon: Icon(Icons.directions_bus), -// child: Text( -// "Tab2", -// ), -// ), -// Tab( -// icon: Icon(Icons.directions_railway), -// child: Text( -// "Tab3", -// ), -// ), -// ], -// tabBarView: GFTabBarView( -// children: [ -// Container(child: Icon(Icons.directions_bike), color: Colors.red,), -// Container(child: Icon(Icons.directions_bus), color: Colors.blue,), -// Container(child: Icon(Icons.directions_railway), color: Colors.orange,), -// Container(child: Icon(Icons.directions_bike), color: Colors.red,), -// Container(child: Icon(Icons.directions_bus), color: Colors.blue,), -// Container(child: Icon(Icons.directions_railway), color: Colors.orange,), -// ], -// ), -// ), - -// GFSocialButton( -// text: 'social goodies', -// onPressed: (){}, -//// icon: GFBadge( -//// child: Text("12"), -//// color: GFColors.DARK, -////// shape: GFBadgeShape.circle, -////// size: GFSize.small, -////// border: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid), -////// textColor: GFColors.WHITE, -////// textStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: 8.0), -//// ), -// type: GFButtonType.outline2x, -// shape: GFButtonShape.pills, -//// blockButton: true, -// fullWidthButton: true, -// -// ), -// -// GFButton( -//// position: GFPosition.end, -//// icon: GFBadge( -//// child: Text("12"), -//// color: GFColors.DARK, -////// shape: GFBadgeShape.circle, -////// size: GFSize.small, -////// border: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid), -////// textColor: GFColors.WHITE, -////// textStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: 8.0), -//// ), -// text: 'goodies', -// onPressed: () {}, -//// textColor: GFColors.danger, -//// icon: Icon(Icons.access_alarms), -//// hoverColor: GFColors.DARK, -// color: GFColors.SECONDARY, -//// focusColor: GFColors.danger, -//// type: GFButtonType.solid, -//// shape: GFButtonShape.pills, -//// buttonBoxShadow: true, -//// boxShadow: BoxShadow( -//// color: Colors.pink, -//// blurRadius: 2.0, -//// spreadRadius: 1.0, -//// offset: Offset.zero, -//// ), -//// splashColor: GFColors.WARNING, -//// highlightColor: GFColors.ALT, -//// size: GFSize.large, -//// disabledColor: GFColors.DARK, -//// disabledTextColor: GFColors.light, -//// blockButton: true, -//// fullWidthButton: true, -//// 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), -// ), -// -// GFIconButton( -// onPressed: null, -// icon: Icon(Icons.ac_unit,), -//// iconSize: 12.0, -// type: GFButtonType.solid, -//// shape: GFButtonShape.pills, -//// size: GFSize.large, -// buttonBoxShadow: true, -// color: GFColors.SECONDARY, -//// boxShadow: BoxShadow( -//// color: Colors.pink, -//// blurRadius: 2.0, -//// spreadRadius: 1.0, -//// offset: Offset.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), -// ), -// -// RaisedButton( -// child: Text('goodiesMaterialButton button '), -// onPressed: (){}, -//// color: Colors.blueGrey, -//// hoverColor: Colors.blueGrey, -//// focusColor: Colors.teal, -//// splashColor: Colors.amber, -//// highlightColor: Colors.cyan, -// ), -// -// GFAvatar( -// radius: 80.0, -// backgroundImage: NetworkImage("https://cdn.pixabay.com/photo/2017/12/03/18/04/christmas-balls-2995437_960_720.jpg"), -// ), - -// GFSegmentTabs( -// tabController: tabController, -// length: 6, -// tabs: const [ -// Text( -// '1', -// ), -// Text( -// '2', -// ), -// Text( -// '3', -// ), -// Text( -// '1', -// ), -// Text( -// '2', -// ), -// Text( -// '3', -// ), -// ], -// indicatorColor: Colors.teal, -// border: Border.all(color: Colors.teal), -// labelColor: GFColors.WHITE, -// unselectedLabelColor: Colors.teal, -// labelStyle: TextStyle( -// fontWeight: FontWeight.w500, -// fontSize: 14, -// ), -// unselectedLabelStyle: TextStyle( -// fontWeight: FontWeight.w400, -// fontSize: 12, -// ), -// ), -// -// GFTabBarView( -// height: 200, -// controller: tabController, -// children: [ -// Container(color: Colors.red), -// Container(color: Colors.green), -// Container(color: Colors.blue), -// Container(color: Colors.red), -// Container(color: Colors.green), -// Container(color: Colors.blue) -// ]), -// -// GFItemsCarousel( -// rowCount: 6, -//// itemHeight: 600, -// children: imageList -// .map((url) => Container( -// margin: const EdgeInsets.all(5), -// child: ClipRRect( -// borderRadius: -// const BorderRadius.all(Radius.circular(5)), -// child: Image.network( -// url, -// fit: BoxFit.cover, -// ), -// ), -// )) -// .toList(), -// ), - - CheckboxListTile( - title: Text("title text"), - value: check, - onChanged: (newValue) { - setState(() { - check = newValue; - }); - }, - controlAffinity: ListTileControlAffinity.leading, - ), - - GFCheckboxListTile( - color: Colors.blueGrey.withOpacity(0.3), - title: const Text('title'), - subTitle: const Text('subtitle'), -// avatar: const GFAvatar( -// backgroundColor: GFColors.SUCCESS, -// ), - description: const Text('description'), -// padding: const EdgeInsets.all(16), -// margin: const EdgeInsets.all(16), -// size: 24, -// type: GFCheckboxType.basic, -// checkColor: Colors.white, -// activebgColor: Colors.red, -// inactivebgColor: Colors.red.withOpacity(0.3), -// activeBorderColor: Colors.red, -// inactiveBorderColor: Colors.red.withOpacity(0.3), -// custombgColor: GFColors.SUCCESS, - value: check, - onChanged: (val) { - setState(() { - check = val; - }); - }, -// inactiveIcon: const Icon( -// Icons.close, -// color: GFColors.DARK, -// size: 16, -// ), -// activeIcon: const Icon( -// Icons.check, -// size: 20, -// color: GFColors.WHITE, -// ), - ), - - Checkbox( - value: check, - onChanged: null, -// (val){ -// print('on change val $val'); -// } - ), - - GFCheckbox( - size: GFSize.SMALL, - activebgColor: GFColors.DANGER, - onChanged: -// null, - (val) { - setState(() { - check = val; - }); - }, - value: check, - inactiveIcon: null, - ), - -// GFCheckbox( -// size: GFSize.SMALL, -// onChanged: (val) { -// print('on change val $val'); -// }, -// value: true, -// type: GFCheckboxType.circle, -// checkColor: GFColors.DANGER, -//// activebgColor: Colors.green, -//// inactivebgColor: Colors.white, -//// activeBorderColor: Colors.red, -// ), -// -// GFRadioButton( -// size: GFSize.SMALL, -// value: true, -// type: GFRadioButtonType.basic, -// radioColor: GFColors.SUCCESS, -//// activebgColor: GFColors.ALT, -//// inactivebgColor: GFColors.PRIMARY, -//// activeBorderColor: GFColors.DANGER, -//// inactiveBorderColor: GFColors.DARK, -// onChanged: (val) { -// print('on change val $val'); -// }, -// activeIcon: const Icon( -// Icons.check, -// size: 20, -// color: GFColors.DARK, -// ), -//// inactiveIcon: const Icon(Icons.close, size: 20, color: GFColors.DARK,), -//// custombgColor: GFColors.SUCCESS, -//// groupValue: -// ), - -// const Padding( -// padding: EdgeInsets.only(left: 15, top: 30), -// child: GFTypography( -// text: 'Basic Checkbox', -// type: GFTypographyType.typo5, -// dividerWidth: 25, -// dividerColor: Color(0xFF19CA4B), -// ), -// ), -// GFCard( -// content: Row( -// mainAxisAlignment: MainAxisAlignment.spaceBetween, -// children: [ -// GFCheckbox( -// size: GFSize.SMALL, -// activebgColor: GFColors.DANGER, -// onChanged: (val) { -// print('on change val $val'); -// }, -// value: true, -// inactiveIcon: null, -// ), -// GFCheckbox( -// activebgColor: GFColors.SECONDARY, -// onChanged: (val) { -// print('on change val $val'); -// }, -// value: true, -// inactiveIcon: null, -// ), -// GFCheckbox( -// size: GFSize.LARGE, -// activebgColor: GFColors.SUCCESS, -// onChanged: (val) { -// print('on change val $val'); -// }, -// value: true, -// inactiveIcon: null, -// ), -// ], -// ), -// ), -// const Padding( -// padding: EdgeInsets.only(left: 15, top: 30), -// child: GFTypography( -// text: 'Square Checkbox', -// type: GFTypographyType.typo5, -// dividerWidth: 25, -// dividerColor: Color(0xFF19CA4B), -// ), -// ), -// GFCard( -// content: Row( -// mainAxisAlignment: MainAxisAlignment.spaceBetween, -// children: [ -// GFCheckbox( -// size: GFSize.SMALL, -// activebgColor: GFColors.ALT, -// type: GFCheckboxType.square, -// onChanged: (val) { -// print('on change val $val'); -// }, -// value: true, -// inactiveIcon: null, -// ), -// GFCheckbox( -// type: GFCheckboxType.square, -// activebgColor: GFColors.INFO, -// onChanged: (val) { -// print('on change val $val'); -// }, -// value: true, -// inactiveIcon: null, -// ), -// GFCheckbox( -// size: GFSize.LARGE, -// activebgColor: GFColors.DARK, -// type: GFCheckboxType.square, -// onChanged: (val) { -// print('on change val $val'); -// }, -// value: true, -// inactiveIcon: null, -// ), -// ], -// ), -// ), -// const Padding( -// padding: EdgeInsets.only(left: 15, top: 30), -// child: GFTypography( -// text: 'Circular Checkbox', -// type: GFTypographyType.typo5, -// dividerWidth: 25, -// dividerColor: Color(0xFF19CA4B), -// ), -// ), -// GFCard( -// content: Row( -// mainAxisAlignment: MainAxisAlignment.spaceBetween, -// children: [ -// GFCheckbox( -// size: GFSize.SMALL, -// type: GFCheckboxType.circle, -// onChanged: (val) { -// print('on change val $val'); -// }, -// value: true, -// inactiveIcon: null, -// ), -// GFCheckbox( -// type: GFCheckboxType.circle, -// activebgColor: GFColors.WARNING, -// onChanged: (val) { -// print('on change val $val'); -// }, -// value: true, -// ), -// GFCheckbox( -// activebgColor: GFColors.SECONDARY, -// size: GFSize.LARGE, -// type: GFCheckboxType.circle, -// onChanged: (val) { -// print('on change val $val'); -// }, -// value: true, -// inactiveIcon: null, -// ), -// ], -// ), -// ), -// const Padding( -// padding: EdgeInsets.only(left: 15, top: 30), -// child: GFTypography( -// text: 'Custom Checkbox', -// type: GFTypographyType.typo5, -// dividerWidth: 25, -// dividerColor: Color(0xFF19CA4B), -// ), -// ), -// GFCard( -// content: Row( -// mainAxisAlignment: MainAxisAlignment.spaceBetween, -// children: [ -// GFCheckbox( -// size: GFSize.SMALL, -// type: GFCheckboxType.custom, -// onChanged: (val) { -// print('on change val $val'); -// }, -// value: true, -// inactiveIcon: null, -// ), -// GFCheckbox( -// type: GFCheckboxType.square, -// activebgColor: GFColors.INFO, -// activeIcon: Icon(Icons.sentiment_satisfied), -// onChanged: (val) { -// print('on change val $val'); -// }, -// value: true, -// inactiveIcon: Icon(Icons.sentiment_dissatisfied), -// ), -// GFCheckbox( -// size: GFSize.MEDIUM, -//// activebgColor: GFColors., -// type: GFCheckboxType.custom, -// onChanged: (val) { -// print('on change val $val'); -// }, -// value: true, -// custombgColor: Colors.purple, -// inactiveIcon: null, -// ), -// ], -// ), -// ), - -// - -// -// GFCarousel( -//// initialPage: 1, -// pagerSize: 12, -// activeIndicator: Colors.pink, -// passiveIndicator: Colors.pink.withOpacity(0.4), -// viewportFraction: 1.0, -//// aspectRatio: 1, -// autoPlay: true, -// enlargeMainPage: true, -// pagination: true, -// items: imageList -// .map((url) => Container( -// padding: const EdgeInsets.only(bottom: 16), -// margin: const EdgeInsets.all(12), -// child: ClipRRect( -// borderRadius: -// const BorderRadius.all(Radius.circular(5)), -// child: Image.network(url, -// fit: BoxFit.cover, width: 1000), -// ), -// )) -// .toList(), -//// onPageChanged: (int index) { -//// setState(() { -//// index; -//// }); -//// }, -// ), - -// -// GFCarousel( -// 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( -//// gradient: LinearGradient( -//// begin: FractionalOffset.bottomLeft, -//// end: FractionalOffset.topRight, -//// colors: [ -//// const Color(0x5a0b486b), -//// const Color(0xFFF56217), -//// ]), -// padding: EdgeInsets.all(0), -// boxFit: BoxFit.fill, -//// colorFilter: new ColorFilter.mode( -//// Colors.black.withOpacity(0.67), BlendMode.DARKen), -// image: Image.network( -// 'https://cdn.pixabay.com/photo/2020/03/11/01/53/landscape-4920705_960_720.jpg', -// fit: BoxFit.fill -// ), -////borderRadius: BorderRadius.vertical(top: Radius.circular(20)), -//shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), -//// imageOverlay: NetworkImage('https://cdn.pixabay.com/photo/2020/03/11/01/53/landscape-4920705_960_720.jpg',), -// titlePosition: GFPosition.end, -// title: GFListTile( -// avatar: GFAvatar( -// backgroundColor: Color(0x5a0b486b), -// child: Text("tb"), -// ), -// title: Text( -// 'Flutter', -// ), -// subTitle: Text( -// "Flutter is Google's mobile UI", -// ), -// description: Text( -// "Flutter Flutter is Google's mobile UI framework for crafting"), -// icon: GFIconButton( -// onPressed: null, -// icon: Icon(Icons.favorite), -// type: GFButtonType.transparent, -// ), -// ), -//// borderOnForeground: true, -// content: Text( -// "Flutter Flutter is Google's mobile UI framework for crafting" -// "Flutter Flutter is Google's mobile UI framework for crafting" -// "Flutter Flutter is Google's mobile UI framework for crafting", -// ), -// buttonBar: GFButtonBar( -// children: [ -// GFButton( -// onPressed: null, -// child: Text("favorite"), -// icon: Icon(Icons.favorite_border), -// type: GFButtonType.transparent, -// ), -// GFButton( -// onPressed: null, -// child: Text("share"), -// icon: Icon(Icons.share), -// type: GFButtonType.outline, -// ), -// GFButton( -// onPressed: null, -// child: Text("share"), -// icon: Icon(Icons.share), -// ), -// ], -// ), -// ), - -// GFButtonBar( -// mainAxisSize: MainAxisSize.min, -// children: [ -// GFButton( -// onPressed: null, -// child: Text("like"), -// icon: Icon(Icons.favorite_border), -// type: GFButtonType.transparent, -// ), -// GFButton( -// onPressed: null, -// child: Text("comment"), -// ), -// GFButton( -// color: Colors.teal, -// onPressed: (){}, -// child: Text("share"), -// icon: Icon(Icons.share), -// type: GFButtonType.outline, -// ), -// ], -// ), -// -// -// GFListTile( -// color: Colors.red, -// avatar: GFAvatar( -// child: Text("tb"), -// ), -// title: Text('title'), -// subTitle: Text('subtitle'), -// icon: GFIconButton( -// onPressed: null, -// type: GFButtonType.transparent, -// icon: Icon(Icons.favorite_border), -// ), -// ), - -// GFImageOverlay( -// width: MediaQuery.of(context).size.width, -// margin: const EdgeInsets.all(16), -// padding: const EdgeInsets.all(16), -// child: Column( -// children: [ -// Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// Text( -// 'Hello world', -// style: TextStyle(color: Colors.white), -// ), -// ], -// ), -// color: Colors.orange, -// image: const NetworkImage( -// 'https://cdn.pixabay.com/photo/2017/12/13/00/23/christmas-3015776_960_720.jpg'), -// boxFit: BoxFit.fitHeight, -// colorFilter: ColorFilter.mode( -// Colors.black.withOpacity(0.6), BlendMode.darken), -// borderRadius: BorderRadius.circular(5), -//// border: Border.all(color: Colors.pink, width: 2.0), -// ), - -// GFAvatar( - // radius: 20.0, -// maxRadius: 50, - -// child: Text("de"), - -// backgroundColor: Colors.pink, -// -//// backgroundImage: , -// -// foregroundColor: Colors.deepOrangeAccent, -// -// shape: GFAvatarShape.square, -// -// size: GFSize.large, -// -// borderRadius: BorderRadius.circular(10.0), -// ), - -// const GFIconBadge( -// child: GFAvatar( -// backgroundColor: GFColors.SUCCESS, -// ), -// counterChild: GFBadge( -// text: '12', -// ), -// ), - -// GFIconButton( -// onPressed: () {}, -// icon: Icon(Icons.ac_unit), -//// iconSize: 12.0, -//// type: GFType.solid, -//// shape: GFIconButtonShape.pills, -//// size: GFSize.large, -//// buttonBoxShadow: true, -//// color: GFColors.WARNING, -//// boxShadow: BoxShadow( -//// color: Colors.pink, -//// blurRadius: 2.0, -//// spreadRadius: 1.0, -//// offset: Offset.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), -// ), -// -// GFBadge( -// text: '12', -//// color: GFColors.DARK, -// shape: GFBadgeShape.circle, -//// size: GFSize.small, -//// border: BorderSide(color: Colors.pink, width: 1.0, style: BorderStyle.solid), -//// textColor: GFColors.WHITE, -//// textStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: 8.0), -// ), -// -// GFButton( -// type: GFButtonType.outline, -// shape: GFButtonShape.pills, -// text: 'goodies', -// icon: Icon(Icons.share), -// onPressed: () {}, -//// hoverColor: Colors.orange, -//// focusColor: Colors.teal, -//// textStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: 8.0), -//// size: GFSize.large, -//// buttonBoxShadow: true, -//// blockButton: true, -//// fullWidthButton: true, -//// color: GFColors.PRIMARY, -//// textColor: GFColors.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, -//// ), -//// 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), -// ), - ], - ), + ), + stickyFooter: Container( + color: Theme.of(context).primaryColor, + height: 100, + child: const Center( + child: Text('I am Footer!'), ), -// bottomNavigationBar: GFTabBar( -// length: 6, -// isScrollable: true, -// controller: tabController, -// tabs: const [ -// Text( -// 'Tab1', -// ), -// Text( -// 'Tab2', -// ), -// Tab( -// icon: Icon(Icons.directions_railway), -// child: Text( -// 'Tab3', -// ), -// ), -// Text( -// 'Tab1', -// ), -// Text( -// 'Tab2', -// ), -// Tab( -// icon: Icon(Icons.directions_railway), -// child: Text( -// 'Tab3', -// ), -// ), -// ], -//// shape: RoundedRectangleBorder( -//// borderRadius: BorderRadius.only( -//// topLeft: Radius.circular(24.0), -//// topRight: Radius.circular(24.0))), -// indicatorColor: GFColors.WHITE, -//// indicatorSize: TabBarIndicatorSize.label, -//// labelColor: Colors.lightGreen, -//// labelPadding: EdgeInsets.all(8.0), -//// tabBarColor: Colors.blueGrey, -//// unselectedLabelColor: Colors.black, -//// labelStyle: TextStyle( -//// fontWeight: FontWeight.w500, -//// fontSize: 13, -//// color: Colors.deepOrange, -//// fontFamily: 'OpenSansBold', -//// ), -//// unselectedLabelStyle: TextStyle( -//// fontWeight: FontWeight.w500, -//// fontSize: 13, -//// color: Colors.black, -//// fontFamily: 'OpenSansBold', -//// ), -// ), - ); + ), + stickyFooterHeight: 50, + ), + floatingActionButton: FloatingActionButton( + child: const Icon(Icons.stars), + onPressed: () { +// _persistentBottomSheet(); +// _modalBottomSheetMenu(); + _controller.isBottomSheetOpened + ? _controller.hideBottomSheet() + : _controller.showBottomSheet(); + }), + ); } diff --git a/example/pubspec.lock b/example/pubspec.lock index ebc1d1bd..e69de29b 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -1,264 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - archive: - dependency: transitive - description: - name: archive - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.11" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.2" - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.2" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.11" - convert: - dependency: transitive - description: - name: convert - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_svg: - dependency: "direct main" - description: - name: flutter_svg - url: "https://pub.dartlang.org" - source: hosted - version: "0.17.1" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - getwidget: - dependency: "direct main" - description: - path: ".." - relative: true - source: path - version: "1.1.3" - image: - dependency: transitive - description: - name: image - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.4" - path_drawing: - dependency: transitive - description: - name: path_drawing - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.1" - path_parsing: - dependency: transitive - description: - name: path_parsing - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.4" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - petitparser: - dependency: transitive - description: - name: petitparser - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.5" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.11" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - url_launcher: - dependency: "direct main" - description: - name: url_launcher - url: "https://pub.dartlang.org" - source: hosted - version: "5.4.1" - url_launcher_macos: - dependency: transitive - description: - name: url_launcher_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+2" - url_launcher_platform_interface: - dependency: transitive - description: - name: url_launcher_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - url_launcher_web: - dependency: transitive - description: - name: url_launcher_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" - xml: - dependency: transitive - description: - name: xml - url: "https://pub.dartlang.org" - source: hosted - version: "3.5.0" -sdks: - dart: ">=2.4.0 <3.0.0" - flutter: ">=1.12.8 <2.0.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 1bda3570..3aa763ea 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: getwidget: path: ../ cupertino_icons: ^0.1.2 - flutter_svg: ^0.17.1 + flutter_svg: ^0.18.0 url_launcher: ^5.4.1 dev_dependencies: diff --git a/lib/components/accordian/gf_accordian.dart b/lib/components/accordian/gf_accordian.dart index 82e0acfa..84fb3c32 100644 --- a/lib/components/accordian/gf_accordian.dart +++ b/lib/components/accordian/gf_accordian.dart @@ -6,21 +6,23 @@ class GFAccordion extends StatefulWidget { {Key key, this.titleChild, this.content, - this.collapsedTitlebackgroundColor = GFColors.WHITE, - this.expandedTitlebackgroundColor = const Color(0xFFE0E0E0), + this.collapsedTitleBackgroundColor = GFColors.WHITE, + this.expandedTitleBackgroundColor = const Color(0xFFE0E0E0), this.collapsedIcon = const Icon(Icons.keyboard_arrow_down), this.expandedIcon = const Icon(Icons.keyboard_arrow_up), this.title, this.textStyle = const TextStyle(color: Colors.black, fontSize: 16), this.titlePadding = const EdgeInsets.all(10), - this.contentbackgroundColor, + this.contentBackgroundColor, this.contentPadding = const EdgeInsets.all(10), this.contentChild, - this.titleborder = const Border(), - this.contentBorder = const Border(), + this.titleBorder = const Border(), + this.contentborder = const Border(), this.margin, this.showAccordion = false, - this.onToggleCollapsed}) + this.onToggleCollapsed, + this.titleBorderRadius = const BorderRadius.all(Radius.circular(0)), + this.contentBorderRadius = const BorderRadius.all(Radius.circular(0))}) : super(key: key); final Function(bool) onToggleCollapsed; @@ -38,10 +40,10 @@ class GFAccordion extends StatefulWidget { final Widget contentChild; /// type of [Color] or [GFColors] which is used to change the background color of the [GFAccordion] title when it is collapsed - final Color collapsedTitlebackgroundColor; + final Color collapsedTitleBackgroundColor; /// type of [Color] or [GFColors] which is used to change the background color of the [GFAccordion] title when it is expanded - final Color expandedTitlebackgroundColor; + final Color expandedTitleBackgroundColor; ///collapsedIcon of type [Widget] which is used to show when the [GFAccordion] is collapsed final Widget collapsedIcon; @@ -62,16 +64,22 @@ class GFAccordion extends StatefulWidget { final EdgeInsets contentPadding; /// type of [Color] or [GFColors] which is used to change the background color of the [GFAccordion] description - final Color contentbackgroundColor; + final Color contentBackgroundColor; ///margin of type [EdgeInsets] which is used to set the margin of the [GFAccordion] final EdgeInsets margin; - ///titleborderColor of type [Color] or [GFColors] which is used to change the border color of title - final Border titleborder; + ///titleBorderColor of type [Color] or [GFColors] which is used to change the border color of title + final Border titleBorder; ///contentBorderColor of type [Color] or [GFColors] which is used to change the border color of content - final Border contentBorder; + final Border contentborder; + + ///titleBorderRadius of type [Radius] which is used to change the border radius of title + final BorderRadius titleBorderRadius; + + ///contentBorderRadius of type [Radius] which is used to change the border radius of content + final BorderRadius contentBorderRadius; @override _GFAccordionState createState() => _GFAccordionState(); @@ -89,10 +97,8 @@ class _GFAccordionState extends State showAccordion = widget.showAccordion; animationController = AnimationController( duration: const Duration(seconds: 2), - vsync: this, ); controller = AnimationController( - vsync: this, duration: const Duration(milliseconds: 300), ); offset = Tween( @@ -124,10 +130,11 @@ class _GFAccordionState extends State onTap: _toggleCollapsed, child: Container( decoration: BoxDecoration( - border: widget.titleborder, + borderRadius: widget.titleBorderRadius, + border: widget.titleBorder, color: showAccordion - ? widget.expandedTitlebackgroundColor - : widget.collapsedTitlebackgroundColor, + ? widget.expandedTitleBackgroundColor + : widget.collapsedTitleBackgroundColor, ), padding: widget.titlePadding, child: Row( @@ -146,8 +153,9 @@ class _GFAccordionState extends State showAccordion ? Container( decoration: BoxDecoration( - border: widget.contentBorder, - color: widget.contentbackgroundColor ?? Colors.white70, + borderRadius: widget.contentBorderRadius, + border: widget.contentborder, + color: widget.contentBackgroundColor ?? Colors.white70, ), width: MediaQuery.of(context).size.width, padding: widget.contentPadding, diff --git a/lib/components/alert/gf_alert.dart b/lib/components/alert/gf_alert.dart index c22306b3..13f062d8 100644 --- a/lib/components/alert/gf_alert.dart +++ b/lib/components/alert/gf_alert.dart @@ -68,7 +68,6 @@ class _GFAlertState extends State with TickerProviderStateMixin { void initState() { animationController = AnimationController( duration: const Duration(milliseconds: 300), - vsync: this, ); animation = CurvedAnimation( parent: animationController, @@ -109,7 +108,7 @@ class _GFAlertState extends State with TickerProviderStateMixin { : GFColors.WHITE, boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.40), blurRadius: 3) + color: Colors.black.withOpacity(0.10), blurRadius: 2) ]), child: Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/components/animation/gf_animation.dart b/lib/components/animation/gf_animation.dart new file mode 100644 index 00000000..f006e3ed --- /dev/null +++ b/lib/components/animation/gf_animation.dart @@ -0,0 +1,290 @@ +import 'package:flutter/material.dart'; +import 'package:getwidget/types/gf_animation_type.dart'; + +class GFAnimation extends StatefulWidget { + const GFAnimation({ + Key key, + this.duration, + this.alignment, + this.child, + this.curve, + this.type, + this.width, + this.height, + this.activeColor, + this.color, + this.padding, + this.activeAlignment, + this.onTap, + this.margin, + this.turnsAnimation, + this.scaleAnimation, + this.controller, + this.textDirection, + this.slidePosition, + this.style, + this.textAlign, + this.textOverflow, + this.maxLines, + this.textWidthBasis, + this.fontSize, + this.fontWeight, + this.changedWidth, + this.changedHeight, + }) : super(key: key); + + /// The duration for animations of the [Decoration]. + final Duration duration; + + /// Defines how the animated widget is aligned within the Animation. + final Alignment alignment; + + /// Defines how the animated widget is aligned(after the onTap) within the Animation. + final Alignment activeAlignment; + + /// The child of type [Widget] to display animation effect. + final Widget child; + + /// Determines the animation curve physics. Defaults to [Curves.linear]. + final Curve curve; + + ///type of [GFAnimation] which takes the type ie, align, size, container, rotateTransition, scaleTransition, slideTransition, and textStyle for the [GFAnimation] + final GFAnimationType type; + + /// [AnimatedContainer] initial width + final double width; + + /// [AnimatedContainer] changed width + final double changedWidth; + + /// [AnimatedContainer] initial height + final double height; + + /// [AnimatedContainer] changed height + final double changedHeight; + + /// defines the color of items when onTap triggers + final Color activeColor; + + /// defines the color of items + final Color color; + + /// The empty space that surrounds the animation. Defines the animation outer [Container.padding].. + final EdgeInsetsGeometry padding; + + /// The empty space that surrounds the animation. Defines the animation outer [Container.margin]. + final EdgeInsetsGeometry margin; + final Function onTap; + + /// Here's an illustration of the [RotationTransition] widget, with it's [turnsAnimation] + /// animated by a [Tween] set to [animate]: + final Animation turnsAnimation; + + /// Here's an illustration of the [ScaleTransition] widget, with it's [scaleAnimation] + /// animated by a [CurvedAnimation] set to [Curves.linear]: + final Animation scaleAnimation; + + final AnimationController controller; + + ///direction of the [AnimatedDefaultTextStyle] TextDirection for [ltr,rtl] + final TextDirection textDirection; + + /// * [ScaleTransition], which animates the scale of a widget. + final Animation slidePosition; + final TextStyle style; + final TextAlign textAlign; + final TextOverflow textOverflow; + + /// [AnimatedDefaultTextStyle] maxlines + final int maxLines; + final TextWidthBasis textWidthBasis; + final double fontSize; + final FontWeight fontWeight; + + @override + _GFAnimationState createState() => _GFAnimationState(); +} + +class _GFAnimationState extends State + with SingleTickerProviderStateMixin { + bool selected = false; + + AnimationController controller; + Animation animation; + Animation offsetAnimation; + + @override + void initState() { + if (widget.type == GFAnimationType.rotateTransition) { + controller = widget.controller ?? + AnimationController( + duration: widget.duration ?? const Duration(seconds: 2)); + animation = widget.turnsAnimation ?? + Tween(begin: 0, end: 20).animate(controller); + if (widget.turnsAnimation == null) { + controller.forward(); + } + } else if (widget.type == GFAnimationType.scaleTransition) { + controller = widget.controller ?? + AnimationController( + duration: widget.duration ?? const Duration(seconds: 2)); + animation = widget.scaleAnimation ?? + CurvedAnimation( + parent: controller, curve: widget.curve ?? Curves.ease); + controller.forward(); + } else if (widget.type == GFAnimationType.slideTransition) { + controller = AnimationController( + duration: widget.duration ?? const Duration(seconds: 2), + )..repeat(reverse: true); + offsetAnimation = Tween( + begin: Offset.zero, + end: const Offset(1.5, 0), + ).animate(CurvedAnimation( + parent: controller, + curve: Curves.linear, + )); + } + super.initState(); + } + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) => getAnimatedTypeWidget(); + + Widget buildAnimatedContainerWidget() => GestureDetector( + onTap: () { + if (mounted) { + setState(() { + selected = !selected; + }); + } + }, + child: AnimatedContainer( + margin: widget.margin ?? const EdgeInsets.all(0), + padding: widget.padding ?? const EdgeInsets.all(8), + width: + selected ? widget.changedWidth ?? 200.0 : widget.width ?? 100.0, + height: + selected ? widget.changedHeight ?? 200.0 : widget.height ?? 100.0, + color: selected + ? widget.activeColor ?? Colors.red + : widget.color ?? Colors.blue, + alignment: selected + ? widget.activeAlignment ?? Alignment.center + : widget.alignment ?? Alignment.center, + duration: widget.duration ?? const Duration(milliseconds: 2000), + curve: widget.curve ?? Curves.linear, + child: widget.child, + ), + ); + + Widget buildAnimatedAlignWidget() => GestureDetector( + onTap: () { + if (widget.onTap == null) { + if (mounted) { + setState(() { + selected = !selected; + }); + } + } else { + widget.onTap(); + } + }, + child: Container( + margin: widget.margin ?? const EdgeInsets.all(0), + padding: widget.padding ?? const EdgeInsets.all(0), + child: AnimatedAlign( + curve: widget.curve ?? Curves.linear, + alignment: selected + ? widget.alignment ?? Alignment.center + : Alignment.topCenter, + duration: widget.duration ?? const Duration(seconds: 2), + child: widget.child, + ), + ), + ); + + Widget buildAnimatedSizeWidget() => GestureDetector( + onTap: widget.onTap, + child: Container( + margin: widget.margin ?? const EdgeInsets.all(0), + padding: widget.padding ?? const EdgeInsets.all(0), + color: widget.color ?? Colors.white, + child: AnimatedSize( + alignment: widget.alignment ?? Alignment.center, + curve: widget.curve ?? Curves.linear, + vsync: this, + duration: widget.duration ?? const Duration(milliseconds: 2000), + child: widget.child, + ), + ), + ); + + Widget buildRotationTransitionWidget() => RotationTransition( + turns: animation, + child: widget.child, + alignment: widget.alignment, + ); + + Widget buildScaleTransitionWidget() => ScaleTransition( + child: widget.child, + scale: animation, + alignment: widget.alignment ?? Alignment.center, + ); + + Widget buildSlideTransitionWidget() => SlideTransition( + child: widget.child, + textDirection: widget.textDirection ?? TextDirection.ltr, + position: widget.slidePosition ?? offsetAnimation, + ); + + Widget buildAnimatedDefaultTextStyleWidget() => GestureDetector( + onTap: widget.onTap, + child: AnimatedDefaultTextStyle( + maxLines: widget.maxLines, + style: widget.style ?? + TextStyle( + fontWeight: widget.fontWeight ?? FontWeight.normal, + fontSize: widget.fontSize ?? 16, + color: widget.color ?? Colors.blue), + textWidthBasis: widget.textWidthBasis ?? TextWidthBasis.parent, + textAlign: widget.textAlign ?? TextAlign.start, + curve: widget.curve ?? Curves.linear, + duration: widget.duration ?? const Duration(seconds: 2), + child: widget.child, + ), + ); + + Widget getAnimatedTypeWidget() { + switch (widget.type) { + case GFAnimationType.align: + return buildAnimatedAlignWidget(); + break; + case GFAnimationType.container: + return buildAnimatedContainerWidget(); + break; + case GFAnimationType.size: + return buildAnimatedSizeWidget(); + break; + case GFAnimationType.rotateTransition: + return buildRotationTransitionWidget(); + break; + case GFAnimationType.scaleTransition: + return buildScaleTransitionWidget(); + break; + case GFAnimationType.slideTransition: + return buildSlideTransitionWidget(); + break; + case GFAnimationType.textStyle: + return buildAnimatedDefaultTextStyleWidget(); + break; + default: + return buildAnimatedContainerWidget(); + } + } +} diff --git a/lib/components/appbar/gf_appbar.dart b/lib/components/appbar/gf_appbar.dart index d8905d0e..d32582e7 100644 --- a/lib/components/appbar/gf_appbar.dart +++ b/lib/components/appbar/gf_appbar.dart @@ -293,6 +293,7 @@ class _GFAppBarState extends State { static const double _defaultElevation = 4; Widget searchBar; bool showSearchBar = false; + final TextEditingController _searchController = TextEditingController(); void _handleDrawerButton() { Scaffold.of(context).openDrawer(); @@ -455,7 +456,7 @@ class _GFAppBarState extends State { ), onTap: widget.onTap, onChanged: widget.onChanged, - controller: widget.searchController, + controller: _searchController ?? widget.searchController, onSubmitted: widget.onSubmitted, ); } @@ -524,7 +525,7 @@ class _GFAppBarState extends State { ); } - // The padding applies to the toolbar and tabbar, not the flexible space. + // The padding applies to the toolbar and tabBar, not the flexible space. if (widget.primary) { appBar = SafeArea( top: true, diff --git a/lib/components/border/gf_border.dart b/lib/components/border/gf_border.dart new file mode 100644 index 00000000..3f74b802 --- /dev/null +++ b/lib/components/border/gf_border.dart @@ -0,0 +1,76 @@ +import 'dart:ui'; +import 'package:flutter/material.dart'; +import 'package:getwidget/components/border/gf_dashed_border.dart'; +import 'package:getwidget/types/gf_border_type.dart'; + +class GFBorder extends StatelessWidget { + GFBorder({ + @required this.child, + this.color = Colors.black, + this.strokeWidth = 1, + this.type = GFBorderType.Rect, + this.dashedLine = const [3, 1], + this.padding = const EdgeInsets.all(10), + this.radius = const Radius.circular(0), + this.customPath, + }) : assert(child != null), + assert(_isValiddashedLine(dashedLine), 'Invalid dash pattern'); + + /// child of type [Widget] which can be any component or text , etc + final Widget child; + + /// padding of time [EdgeInsets] where in padding is given to the border types + final EdgeInsets padding; + + /// storkeWidth of type [double] which is used to define the thickness of the border + final double strokeWidth; + + /// color of type [Color] or GFColor which is used to change the color of the border type + final Color color; + + /// dashedLine of type [List] which is used for the linear and simple dashed line of border + final List dashedLine; + + /// type of [GFBorderType] which is used to define the different types of borders ie, circle, Rect, RRect and oval + final GFBorderType type; + + /// radius of type [Radius] used to give a curved border only when the border type is RRect, in other cases radius will not work + final Radius radius; + + /// customPath of type [PathBuilder] used for drawing the paths + final PathBuilder customPath; + + @override + Widget build(BuildContext context) => Stack( + children: [ + Positioned.fill( + child: CustomPaint( + painter: DashedType( + strokeWidth: strokeWidth, + radius: radius, + color: color, + type: type, + dashedLine: dashedLine, + customPath: customPath, + ), + ), + ), + Container(padding: padding, child: child), + ], + ); +} + +/// the value of dashedLine cannot be 0 or null, it should have some definite and proper value +bool _isValiddashedLine(List dash) { + final Set _dashSet = dash.toSet(); + if (_dashSet == null) { + return false; + } + if (_dashSet.length == 1 && _dashSet.elementAt(0) == 0.0) { + return false; + } + if (_dashSet.isEmpty) { + return false; + } + return true; +} diff --git a/lib/components/border/gf_dashed_border.dart b/lib/components/border/gf_dashed_border.dart new file mode 100644 index 00000000..fc56c3b8 --- /dev/null +++ b/lib/components/border/gf_dashed_border.dart @@ -0,0 +1,199 @@ +import 'dart:ui'; +import 'package:flutter/material.dart'; +import 'package:getwidget/types/gf_border_type.dart'; + +typedef PathBuilder = Path Function(Size); + +class DashedType extends CustomPainter { + DashedType({ + this.strokeWidth = 2, + this.dashedLine = const [3, 1], + this.color = Colors.black, + this.type = GFBorderType.Rect, + this.radius = const Radius.circular(0), + this.customPath, + }) : assert(dashedLine.isNotEmpty, 'dash line cannot be empty'); + + /// storkeWidth of type [double] which is used to define the thickness of the border + final double strokeWidth; + + /// dashedLine of type [List] which is used for the linear and simple dashed line of border + final List dashedLine; + + /// color of type [Color] or GFColor which is used to change the color of the border type + final Color color; + + /// type of [GFBorderType] which is used to define the different types of borders ie, circle, Rect, RRect and oval + final GFBorderType type; + + /// radius of type [Radius] used to give a curved border only when the border type is RRect, in other cases radius will not work + final Radius radius; + + /// customPath of type [PathBuilder] used for the drawing the paths + final PathBuilder customPath; + + @override + void paint(Canvas canvas, Size size) { + final Paint paint = Paint() + ..strokeWidth = strokeWidth + ..color = color + ..style = PaintingStyle.stroke; + + Path _path; + if (customPath != null) { + _path = dashPath( + customPath(size), + dashedarray: CircularIntervalList(dashedLine), + ); + } else { + _path = _getPath(size); + } + + canvas.drawPath(_path, paint); + } + + /// Returns a [Path] based on the the borderType parameter + Path _getPath(Size size) { + Path path; + switch (type) { + case GFBorderType.Circle: + path = _getCirclePath(size); + break; + case GFBorderType.RRect: + path = _getRRectPath(size, radius); + break; + case GFBorderType.Rect: + path = _getRectPath(size); + break; + case GFBorderType.Oval: + path = _getOvalPath(size); + break; + } + + return dashPath(path, dashedarray: CircularIntervalList(dashedLine)); + } + + /// gives a circular path of borderType + Path _getCirclePath(Size size) { + final double width = size.width; + final double height = size.height; + final double sizes = size.shortestSide; + + return Path() + ..addRRect( + RRect.fromRectAndRadius( + Rect.fromLTWH( + width > sizes ? (width - sizes) / 2 : 0, + height > sizes ? (height - sizes / 2) : 0, + sizes, + sizes, + ), + Radius.circular(sizes / 2), + ), + ); + } + + /// gives a Rounded Rectangular Path with [radius] of [size] for borderType + + Path _getRRectPath(Size size, Radius radius) => Path() + ..addRRect( + RRect.fromRectAndRadius( + Rect.fromLTWH( + 0, + 0, + size.width, + size.height, + ), + radius, + ), + ); + + /// gives a Rectangular Path with [size] for borderType + Path _getRectPath(Size size) => Path() + ..addRect( + Rect.fromLTWH( + 0, + 0, + size.width, + size.height, + ), + ); + + /// gives an oval path of [size] for borderType + Path _getOvalPath(Size size) => Path() + ..addOval( + Rect.fromLTWH( + 0, + 0, + size.width, + size.height, + ), + ); + + @override + bool shouldRepaint(DashedType oldDelegate) => + oldDelegate.strokeWidth != strokeWidth || + oldDelegate.color != color || + oldDelegate.dashedLine != dashedLine || + oldDelegate.type != type; +} + +class CircularIntervalList { + CircularIntervalList(this.values); + + final List values; + int index = 0; + + T get next { + if (index >= values.length) { + index = 0; + } + return values[index++]; + } +} + +Path dashPath(Path source, + {@required CircularIntervalList dashedarray, + DashOffset dashOffset = const DashOffset.absolute(0)}) { + assert(dashedarray != null); + if (source == null) { + return null; + } + + final Path dest = Path(); + for (final PathMetric metric in source.computeMetrics()) { + double distance = dashOffset._calculate(metric.length); + bool draw = true; + while (distance < metric.length) { + final double len = dashedarray.next; + if (draw) { + dest.addPath(metric.extractPath(distance, distance + len), Offset.zero); + } + distance += len; + draw = !draw; + } + } + + return dest; +} + +/// Specifies the starting position of a dashed array or line on a path, either as a percentage or absolute +enum _DashOffsetType { Absolute, Percentage } + +class DashOffset { + ///gives offset of the dashed path that will be measured as a percentage which ranges from 0.0 to 1.0 + DashOffset.percentage(double percentage) + : _value = percentage.clamp(0.0, 1.0) ?? 0.0, + _dashOffsetType = _DashOffsetType.Percentage; + + ///gives offset of the dashed path that will be measured as a absolute value + const DashOffset.absolute(double start) + : _value = start ?? 0.0, + _dashOffsetType = _DashOffsetType.Absolute; + + final double _value; + final _DashOffsetType _dashOffsetType; + + double _calculate(double length) => + _dashOffsetType == _DashOffsetType.Absolute ? _value : length * _value; +} diff --git a/lib/components/bottom_sheet/ex.dart b/lib/components/bottom_sheet/ex.dart new file mode 100644 index 00000000..aa63e0cf --- /dev/null +++ b/lib/components/bottom_sheet/ex.dart @@ -0,0 +1,413 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +/// [ExpandableBottomSheet] is a BottomSheet with a draggable height like the +/// Google Maps App on Android. +/// +/// __Example:__ +/// +/// ```dart +/// ExpandableBottomSheet( +/// background: Container( +/// color: Colors.red, +/// child: Center( +/// child: Text('Background'), +/// ), +/// ), +/// persistentHeader: Container( +/// height: 40, +/// color: Colors.blue, +/// child: Center( +/// child: Text('Header'), +/// ), +/// ), +/// expandableContent: Container( +/// height: 500, +/// color: Colors.green, +/// child: Center( +/// child: Text('Content'), +/// ), +/// ), +/// ); +/// ``` +class ExpandableBottomSheet extends StatefulWidget { + /// [expandableContent] is the widget which you can hide and show by dragging. + /// It has to be a widget with a constant height. It is required for the [ExpandableBottomSheet]. + final Widget expandableContent; + + /// [background] is the widget behind the [expandableContent] which holds + /// usually the content of your page. It is required for the [ExpandableBottomSheet]. + final Widget background; + + /// [persistentHeader] is a Widget which is on top of the [expandableContent] + /// and will never be hidden. It is made for a widget which indicates the + /// user he can expand the content by dragging. + final Widget persistentHeader; + + /// [persistentFooter] is a widget which is always shown at the bottom. The [expandableContent] + /// is if it is expanded on top of it so you don't need margin to see all of + /// your content. You can use it for example for navigation or a menu. + final Widget persistentFooter; + + /// [persistentContentHeight] is the height of the content which will never + /// been contracted. It only relates to [expandableContent]. [persistentHeader] + /// and [persistentFooter] will not be affected by this. + final double persistentContentHeight; + + /// [animationDurationExtend] is the duration for the animation if you stop + /// dragging with high speed. + final Duration animationDurationExtend; + + /// [animationDurationContract] is the duration for the animation to bottom + /// if you stop dragging with high speed. If it is `null` [animationDurationExtend] will be used. + final Duration animationDurationContract; + + /// [animationCurveExpand] is the curve of the animation for expanding + /// the [expandableContent] if the drag ended with high speed. + final Curve animationCurveExpand; + + /// [animationCurveContract] is the curve of the animation for contracting + /// the [expandableContent] if the drag ended with high speed. + final Curve animationCurveContract; + + /// [onIsExtendedCallback] will be executed if the extend reaches its maximum. + final Function() onIsExtendedCallback; + + /// [onIsContractedCallback] will be executed if the extend reaches its minimum. + final Function() onIsContractedCallback; + + /// Creates the [ExpandableBottomSheet]. + /// + /// [persistentContentHeight] has to be greater 0. + const ExpandableBottomSheet({ + Key key, + @required this.expandableContent, + @required this.background, + this.persistentHeader, + this.persistentFooter, + this.persistentContentHeight = 0.0, + this.animationCurveExpand = Curves.ease, + this.animationCurveContract = Curves.ease, + this.animationDurationExtend = const Duration(milliseconds: 250), + this.animationDurationContract = const Duration(milliseconds: 250), + this.onIsExtendedCallback, + this.onIsContractedCallback, + }) : assert(expandableContent != null), + assert(background != null), + assert(persistentContentHeight != null && persistentContentHeight >= 0), + assert(animationCurveExpand != null), + assert(animationCurveContract != null), + assert(animationDurationExtend != null), + assert(animationDurationContract != null), + super(key: key); + + @override + ExpandableBottomSheetState createState() => ExpandableBottomSheetState(); +} + +class ExpandableBottomSheetState extends State + with TickerProviderStateMixin { + GlobalKey _contentKey = new GlobalKey(debugLabel: 'contentKey'); + GlobalKey _headerKey = new GlobalKey(debugLabel: 'headerKey'); + GlobalKey _footerKey = new GlobalKey(debugLabel: 'footerKey'); + + AnimationController _controller; + + double _draggableHeight = 0; + double _positionOffset; + double _startOffsetAtDragDown = 0; + double _startPositionAtDragDown = 0; + + double _minOffset = 0; + double _maxOffset = 0; + + double _animationMinOffset = 0; + + AnimationStatus _oldStatus = AnimationStatus.dismissed; + + bool _useDrag = true; + bool _callCallbacks = false; + + /// Expands the content of the widget. + void expand() { + _afterUpdateWidgetBuild(false); + _callCallbacks = true; + _animateToTop(); + } + + /// Contracts the content of the widget. + void contract() { + _afterUpdateWidgetBuild(false); + _callCallbacks = true; + _animateToBottom(); + } + + /// The status of the expansion. + ExpansionStatus get expansionStatus { + if (_positionOffset == null) return ExpansionStatus.contracted; + if (_positionOffset == _maxOffset) return ExpansionStatus.contracted; + if (_positionOffset == _minOffset) return ExpansionStatus.expanded; + return ExpansionStatus.middle; + } + + @override + void initState() { + super.initState(); + _controller = AnimationController( + vsync: this, + lowerBound: 0.0, + upperBound: 1.0, + ); + _controller.addStatusListener(_handleAnimationStatusUpdate); + WidgetsBinding.instance + .addPostFrameCallback((_) => _afterUpdateWidgetBuild(true)); + } + + @override + Widget build(BuildContext context) { + WidgetsBinding.instance + .addPostFrameCallback((_) => _afterUpdateWidgetBuild(false)); + return Column( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: Stack( + overflow: Overflow.clip, + children: [ + Align( + alignment: Alignment.topLeft, + child: widget.background, + ), + AnimatedBuilder( + animation: _controller, + builder: (_, Widget child) { + if (_controller.isAnimating) { + _positionOffset = _animationMinOffset + + _controller.value * _draggableHeight; + } + return Positioned( + top: _positionOffset, + right: 0.0, + left: 0.0, + child: child, + ); + }, + child: GestureDetector( + onVerticalDragDown: _dragDown, + onVerticalDragUpdate: _dragUpdate, + onVerticalDragEnd: _dragEnd, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + key: _headerKey, + child: widget.persistentHeader ?? Container()), + Container( + key: _contentKey, + child: widget.expandableContent, + ), + ], + ), + ), + ) + ], + ), + ), + Container( + key: _footerKey, child: widget.persistentFooter ?? Container()), + ], + ); + } + + void _handleAnimationStatusUpdate(AnimationStatus status) { + if (status == AnimationStatus.completed) { + if (_oldStatus == AnimationStatus.forward) { + setState(() { + _draggableHeight = _maxOffset - _minOffset; + _positionOffset = _minOffset; + }); + if (widget.onIsExtendedCallback != null && _callCallbacks) { + widget.onIsExtendedCallback(); + } + } + if (_oldStatus == AnimationStatus.reverse) { + setState(() { + _draggableHeight = _maxOffset - _minOffset; + _positionOffset = _maxOffset; + }); + if (widget.onIsContractedCallback != null && _callCallbacks) + widget.onIsContractedCallback(); + } + } + } + + void _afterUpdateWidgetBuild(bool isFirstBuild) { + double headerHeight = _headerKey.currentContext.size.height; + double footerHeight = _footerKey.currentContext.size.height; + double contentHeight = _contentKey.currentContext.size.height; + + double checkedPersistentContentHeight = + (widget.persistentContentHeight < contentHeight) + ? widget.persistentContentHeight + : contentHeight; + + _minOffset = + context.size.height - headerHeight - contentHeight - footerHeight; + _maxOffset = context.size.height - + headerHeight - + footerHeight - + checkedPersistentContentHeight; + + if (!isFirstBuild) { + _positionOutOfBounds(); + } else { + setState(() { + _positionOffset = _maxOffset; + _draggableHeight = _maxOffset - _minOffset; + }); + } + } + + void _positionOutOfBounds() { + if (_positionOffset < _minOffset) { + //the extend is larger than contentHeight + _callCallbacks = false; + _animateToMin(); + } else { + if (_positionOffset > _maxOffset) { + //the extend is smaller than persistentContentHeight + _callCallbacks = false; + _animateToMax(); + } else { + _draggableHeight = _maxOffset - _minOffset; + } + } + } + + void _animateOnIsAnimating() { + if (_controller.isAnimating) { + _controller.stop(); + } + } + + void _dragDown(DragDownDetails details) { + if (_controller.isAnimating) { + _useDrag = false; + } else { + _useDrag = true; + _startOffsetAtDragDown = details.localPosition.dy; + _startPositionAtDragDown = _positionOffset; + } + } + + void _dragUpdate(DragUpdateDetails details) { + if (!_useDrag) return; + double offset = details.localPosition.dy; + double newOffset = + _startPositionAtDragDown + offset - _startOffsetAtDragDown; + if (_minOffset <= newOffset && _maxOffset >= newOffset) { + setState(() { + _positionOffset = newOffset; + }); + } else { + if (_minOffset > newOffset) + setState(() { + _positionOffset = _minOffset; + }); + if (_maxOffset < newOffset) + setState(() { + _positionOffset = _maxOffset; + }); + } + } + + void _dragEnd(DragEndDetails details) { + if (_startPositionAtDragDown == _positionOffset || !_useDrag) return; + if (details.primaryVelocity < -250) { + //drag up ended with high speed + _callCallbacks = true; + _animateToTop(); + } else { + if (details.primaryVelocity > 250) { + //drag down ended with high speed + _callCallbacks = true; + _animateToBottom(); + } else { + if (_positionOffset == _maxOffset && + widget.onIsContractedCallback != null) { + widget.onIsContractedCallback(); + } + if (_positionOffset == _minOffset && + widget.onIsExtendedCallback != null) { + widget.onIsExtendedCallback(); + } + } + } + } + + void _animateToTop() { + _animateOnIsAnimating(); + _controller.value = (_positionOffset - _minOffset) / _draggableHeight; + _animationMinOffset = _minOffset; + _oldStatus = AnimationStatus.forward; + _controller.animateTo( + 0.0, + duration: widget.animationDurationExtend, + curve: widget.animationCurveExpand, + ); + } + + void _animateToBottom() { + _animateOnIsAnimating(); + + _controller.value = (_positionOffset - _minOffset) / _draggableHeight; + _animationMinOffset = _minOffset; + _oldStatus = AnimationStatus.reverse; + _controller.animateTo( + 1.0, + duration: + widget.animationDurationContract ?? widget.animationDurationExtend, + curve: widget.animationCurveContract ?? widget.animationCurveExpand, + ); + } + + void _animateToMax() { + _animateOnIsAnimating(); + + _controller.value = 1.0; + _draggableHeight = _positionOffset - _maxOffset; + _animationMinOffset = _maxOffset; + _oldStatus = AnimationStatus.reverse; + _controller.animateTo(0.0, + duration: widget.animationDurationExtend, + curve: widget.animationCurveExpand); + } + + void _animateToMin() { + _animateOnIsAnimating(); + + _controller.value = 1.0; + _draggableHeight = _positionOffset - _minOffset; + _animationMinOffset = _minOffset; + _oldStatus = AnimationStatus.forward; + _controller.animateTo( + 0.0, + duration: + widget.animationDurationContract ?? widget.animationDurationExtend, + curve: widget.animationCurveContract ?? widget.animationCurveExpand, + ); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } +} + +/// The status of the expandable content. +enum ExpansionStatus { + expanded, + middle, + contracted, +} diff --git a/lib/components/bottom_sheet/gf_bottom_sheet.dart b/lib/components/bottom_sheet/gf_bottom_sheet.dart new file mode 100644 index 00000000..8bb9df13 --- /dev/null +++ b/lib/components/bottom_sheet/gf_bottom_sheet.dart @@ -0,0 +1,238 @@ +import 'package:flutter/material.dart'; +import 'dart:async'; + +class GFBottomSheet extends StatefulWidget { + GFBottomSheet({ + Key key, + @required this.stickyHeader, + @required this.contentBody, + this.stickyFooter, + this.controller, + this.minContentHeight = 0, + this.maxContentHeight = 300, + this.elevation = 0.0, + this.stickyFooterHeight, + }) : assert(elevation >= 0.0), + assert(minContentHeight >= 0.0), + super(key: key) { + controller.height = minContentHeight; + controller.smoothness = 500; + } + + /// [minContentHeight] controls the minimum height of the content body. + /// It Must be greater or equal to 0. Default value is 0. + final double minContentHeight; + + /// [maxContentHeight] controls the maximum height of the content body. + /// It Must be greater or equal to 0. Default value is 300. + final double maxContentHeight; + + /// [stickyHeader] is the header of GFBottomSheet. + /// User can interact by swiping or tapping the [stickyHeader] + final Widget stickyHeader; + + /// [contentBody] is the body of GFBottomSheet. + /// User can interact by tapping the [contentBody] + final Widget contentBody; + + /// [stickyFooter] is the footer of GFBottomSheet. + /// User can interact by swiping or tapping the [stickyFooter] + final Widget stickyFooter; + + /// [stickyFooterHeight] defines the height of GFBottokSheet footer. + final double stickyFooterHeight; + + /// [elevation] controls shadow below the GFBottomSheet material. + /// Must be greater or equalto 0. Default value is 0. + final double elevation; + + /// [controller] used to control GFBottomSheet behavior like hide/show + final GFBottomSheetController controller; + + @override + _GFBottomSheetState createState() => _GFBottomSheetState(); +} + +class _GFBottomSheetState extends State + with TickerProviderStateMixin { + bool isDragDirectionUp; + bool showBottomSheet = false; + Function _controllerListener; + + void _onVerticalDragUpdate(data) { + _setSmoothness(); + if (((widget.controller.height - data.delta.dy) > + widget.minContentHeight) && + ((widget.controller.height - data.delta.dy) < + widget.maxContentHeight)) { + isDragDirectionUp = data.delta.dy <= 0; + widget.controller.height -= data.delta.dy; + } + } + + void _onVerticalDragEnd(data) { + _setSmoothness(); + if (isDragDirectionUp && widget.controller.value) { + _showBottomSheet(); + } else if (!isDragDirectionUp && !widget.controller.value) { + _hideBottomSheet(); + } else { + widget.controller.value = isDragDirectionUp; + } + } + + void _onTap() { + final bool isBottomSheetOpened = + widget.controller.height == widget.maxContentHeight; + widget.controller.value = !isBottomSheetOpened; + } + + @override + void initState() { + super.initState(); + position = widget.minContentHeight; + widget.controller.value = showBottomSheet; + _controllerListener = () { + widget.controller.value ? _showBottomSheet() : _hideBottomSheet(); + }; + widget.controller.addListener(_controllerListener); + } + + StreamController controller = StreamController.broadcast(); + double position; + + + @override + Widget build(BuildContext context) { + final BottomSheetThemeData bottomSheetTheme = + Theme.of(context).bottomSheetTheme; + final double elevation = + widget.elevation ?? bottomSheetTheme.elevation ?? 0; + + final Widget bottomSheet = Column( + mainAxisSize: MainAxisSize.min, + children: [ + widget.stickyHeader == null + ? Container() + : GestureDetector( + onVerticalDragUpdate: _onVerticalDragUpdate, + onVerticalDragEnd: _onVerticalDragEnd, + onTap: _onTap, + child: widget.stickyHeader, + ), + + + StreamBuilder( + stream: controller.stream, + builder: (context, snapshot) => GestureDetector( + onVerticalDragUpdate: (DragUpdateDetails details){ + position = MediaQuery.of(context).size.height - details.globalPosition.dy; + print('fff'); + + if(position >= widget.maxContentHeight){ + print('max'); + position = widget.maxContentHeight; + }else if(position <= widget.minContentHeight){ + print('min'); + position = widget.minContentHeight; + _hideBottomSheet(); + } + controller.add(position); + + }, + onVerticalDragEnd: _onVerticalDragEnd, + onTap: _onTap, + behavior: HitTestBehavior.translucent, + child: Container( + color: Colors.red, + height: snapshot.hasData ? snapshot.data : widget.maxContentHeight*0.3, + width: double.infinity, + child: Text('jk'), + ) + ), + ), + + +// AnimatedBuilder( +// animation: widget.controller, +// builder: (_, Widget child) => +// AnimatedContainer( +// curve: Curves.easeOut, +// duration: Duration(milliseconds: widget.controller.smoothness), +// height: widget.controller.height, +// child: GestureDetector( +// onVerticalDragUpdate: _onVerticalDragUpdate, +// onVerticalDragEnd: _onVerticalDragEnd, +// onTap: _onTap, +// child: widget.contentBody +// ), +// ), +// ), + + widget.stickyFooter != null + ? AnimatedBuilder( + animation: widget.controller, + builder: (_, Widget child) => AnimatedContainer( + curve: Curves.easeOut, + duration: Duration( + milliseconds: widget.controller.smoothness), + height: widget.controller.height != + widget.minContentHeight + ? widget.stickyFooterHeight + : 0.0, + child: GestureDetector( + onVerticalDragUpdate: _onVerticalDragUpdate, + onVerticalDragEnd: _onVerticalDragEnd, + onTap: _onTap, + child: widget.stickyFooter, + ), + ), + ) + : Container(), + ], + ); + return Material( + elevation: elevation, + child: bottomSheet, + ); + } + + void _hideBottomSheet() { + widget.controller.height = widget.minContentHeight; + } + + void _showBottomSheet() { + widget.controller.height = widget.maxContentHeight; + } + + @override + void dispose() { + widget.controller.removeListener(_controllerListener); + super.dispose(); + } + + void _setSmoothness() { + widget.controller.smoothness = 500; + } +} + +class GFBottomSheetController extends ValueNotifier { + GFBottomSheetController() : super(false); + + /// Defines the height of the GFBottomSheet's contentBody + double _height; + + /// Defines the drag animation smoothness of the GFBottomSheet + int smoothness; + + // ignore: unnecessary_getters_setters + set height(double value) => _height = value; + + // ignore: unnecessary_getters_setters + double get height => _height; + + bool get isBottomSheetOpened => value; + + void hideBottomSheet() => value = false; + void showBottomSheet() => value = true; +} diff --git a/lib/components/button/gf_button.dart b/lib/components/button/gf_button.dart index 80501483..bd57593c 100644 --- a/lib/components/button/gf_button.dart +++ b/lib/components/button/gf_button.dart @@ -1014,13 +1014,15 @@ class _GFButtonState extends State { bool get _disabled => _states.contains(MaterialState.disabled); double buttonWidth() { + double buttonWidth = 0; if (widget.blockButton == true) { - return MediaQuery.of(context).size.width * 0.88; + buttonWidth = MediaQuery.of(context).size.width * 0.88; } else if (widget.fullWidthButton == true) { - return MediaQuery.of(context).size.width; + buttonWidth = MediaQuery.of(context).size.width; } else { - return MediaQuery.of(context).size.width * 0.88; + buttonWidth = null; } + return buttonWidth; } void _updateState(MaterialState state, bool value) { diff --git a/lib/components/carousel/gf_carousel.dart b/lib/components/carousel/gf_carousel.dart index 9f8cd410..e0248337 100644 --- a/lib/components/carousel/gf_carousel.dart +++ b/lib/components/carousel/gf_carousel.dart @@ -24,7 +24,6 @@ class GFCarousel extends StatefulWidget { this.pauseAutoPlayOnTouch, this.enlargeMainPage = false, this.onPageChanged, -// this.onPageIndex, this.scrollPhysics, this.scrollDirection = Axis.horizontal, }) : realPage = enableInfiniteScroll ? realPage + initialPage : initialPage, diff --git a/lib/components/carousel/gf_items_carousel.dart b/lib/components/carousel/gf_items_carousel.dart index e11d9ee3..87e10542 100644 --- a/lib/components/carousel/gf_items_carousel.dart +++ b/lib/components/carousel/gf_items_carousel.dart @@ -83,7 +83,6 @@ class _GFItemsCarouselState extends State offset = 0; animationController = AnimationController( duration: const Duration(milliseconds: dragAnimationDuration), - vsync: this, ); Future.delayed(Duration.zero, () { setState(() { @@ -133,7 +132,6 @@ class _GFItemsCarouselState extends State animationController = AnimationController( duration: const Duration(milliseconds: dragAnimationDuration), - vsync: this, ); final Tween tween = @@ -165,7 +163,6 @@ class _GFItemsCarouselState extends State final double endAnimation = size * (offset / size).round().toDouble(); animationController = AnimationController( duration: const Duration(milliseconds: shiftAnimationDuration), - vsync: this, ); final Tween tween = Tween(begin: beginAnimation, end: endAnimation); final Animation animation = tween.animate(animationController); diff --git a/lib/components/checkbox/gf_checkbox.dart b/lib/components/checkbox/gf_checkbox.dart index 737a3c9a..e19fa9ca 100644 --- a/lib/components/checkbox/gf_checkbox.dart +++ b/lib/components/checkbox/gf_checkbox.dart @@ -2,25 +2,28 @@ import 'package:flutter/material.dart'; import 'package:getwidget/getwidget.dart'; class GFCheckbox extends StatefulWidget { - const GFCheckbox({ - Key key, - this.size = GFSize.MEDIUM, - this.type = GFCheckboxType.basic, - this.checkColor = GFColors.WHITE, - this.activebgColor = GFColors.PRIMARY, - this.inactivebgColor = GFColors.WHITE, - this.activeBorderColor = GFColors.WHITE, - this.inactiveBorderColor = GFColors.DARK, - this.onChanged, - this.value, - this.activeIcon = const Icon( - Icons.check, - size: 20, - color: GFColors.WHITE, - ), - this.inactiveIcon = const Icon(Icons.close), - this.custombgColor = GFColors.SUCCESS, - }) : super(key: key); + const GFCheckbox( + {Key key, + this.size = GFSize.MEDIUM, + this.type = GFCheckboxType.basic, + this.checkColor = GFColors.WHITE, + this.activebgColor = GFColors.PRIMARY, + this.inactivebgColor = GFColors.WHITE, + this.activeBorderColor = GFColors.WHITE, + this.inactiveBorderColor = GFColors.DARK, + this.onChanged, + this.value, + this.activeIcon = const Icon( + Icons.check, + size: 20, + color: GFColors.WHITE, + ), + this.inactiveIcon = const Icon(Icons.close), + this.custombgColor = GFColors.SUCCESS, + this.autofocus = false, + this.focusNode}) + : assert(autofocus != null), + super(key: key); /// type of [GFCheckboxType] which is of four type is basic, sqaure, circular and custom final GFCheckboxType type; @@ -28,7 +31,7 @@ class GFCheckbox extends StatefulWidget { /// type of [double] which is GFSize ie, small, medium and large and can use any double value final double size; - // type pf [Color] used to change the checkcolor when the checkbox is active + /// type pf [Color] used to change the checkcolor when the checkbox is active final Color checkColor; /// type of [Color] used to change the backgroundColor of the active checkbox @@ -58,40 +61,42 @@ class GFCheckbox extends StatefulWidget { /// type of [Color] used to change the background color of the custom active checkbox only final Color custombgColor; + /// {@macro flutter.widgets.Focus.autofocus} + final bool autofocus; + + /// {@macro flutter.widgets.Focus.focusNode} + final FocusNode focusNode; + @override _GFCheckboxState createState() => _GFCheckboxState(); } class _GFCheckboxState extends State { bool get enabled => widget.onChanged != null; - bool isSelected = false; @override void initState() { super.initState(); - isSelected = widget.value ?? false; - } - - void onStatusChange() { - setState(() { - isSelected = !isSelected; - }); - if (widget.onChanged != null) { - widget.onChanged(isSelected); - } } @override Widget build(BuildContext context) => FocusableActionDetector( + focusNode: widget.focusNode, + autofocus: widget.autofocus, enabled: enabled, child: InkWell( - onTap: onStatusChange, + canRequestFocus: enabled, + onTap: widget.onChanged != null + ? () { + widget.onChanged(!widget.value); + } + : null, child: Container( height: widget.size, width: widget.size, decoration: BoxDecoration( color: enabled - ? isSelected + ? widget.value ? widget.type == GFCheckboxType.custom ? Colors.white : widget.activebgColor @@ -103,12 +108,12 @@ class _GFCheckboxState extends State { ? BorderRadius.circular(50) : BorderRadius.zero, border: Border.all( - color: isSelected + color: widget.value ? widget.type == GFCheckboxType.custom ? Colors.black87 : widget.activeBorderColor : widget.inactiveBorderColor)), - child: isSelected + child: widget.value ? widget.type == GFCheckboxType.custom ? Stack( children: [ diff --git a/lib/components/checkboxListTile/gf_checkbox_list_tile.dart b/lib/components/checkboxListTile/gf_checkbox_list_tile.dart deleted file mode 100644 index dc401b48..00000000 --- a/lib/components/checkboxListTile/gf_checkbox_list_tile.dart +++ /dev/null @@ -1,236 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:getwidget/getwidget.dart'; - -class GFCheckboxListTile extends StatefulWidget { - const GFCheckboxListTile({ - Key key, - this.titleText, - this.subtitleText, - this.color, - this.avatar, - this.title, - this.subTitle, - this.description, - this.padding = const EdgeInsets.all(8), - this.margin = const EdgeInsets.all(16), - this.size = GFSize.MEDIUM, - this.type = GFCheckboxType.basic, - this.checkColor = GFColors.WHITE, - this.activebgColor = GFColors.PRIMARY, - this.inactivebgColor = GFColors.WHITE, - this.activeBorderColor = GFColors.WHITE, - this.inactiveBorderColor = GFColors.DARK, - this.onChanged, - this.value, - this.activeIcon = const Icon( - Icons.check, - size: 20, - color: GFColors.WHITE, - ), - this.inactiveIcon = const Icon(Icons.close), - this.custombgColor = GFColors.SUCCESS, - }) : super(key: key); - - ///type of [String] used to pass text, alternative to title property and gets higher priority than title - final String titleText; - - ///type of [String] used to pass text, alternative to subtitle property and gets higher priority than subtitle - final String subtitleText; - - /// The GFListTile's background color. Can be given [Color] or [GFColors] - final Color color; - - /// type of [Widget] or [GFAvatar] used to create rounded user profile - final Widget avatar; - - /// The title to display inside the [GFListTile]. see [Text] - final Widget title; - - /// The subTitle to display inside the [GFListTile]. see [Text] - final Widget subTitle; - - /// The description to display inside the [GFListTile]. see [Text] - final Widget description; - - /// defines the margin of GFListTile - final EdgeInsets margin; - - /// defines the padding of GFListTile - final EdgeInsets padding; - - /// type of [GFCheckboxType] which is of four type is basic, sqaure, circular and custom - final GFCheckboxType type; - - /// type of [double] which is GFSize ie, small, medium and large and can use any double value - final double size; - - // type pf [Color] used to change the checkcolor when the checkbox is active - final Color checkColor; - - /// type of [Color] used to change the backgroundColor of the active checkbox - final Color activebgColor; - - /// type of [Color] used to change the backgroundColor of the inactive checkbox - final Color inactivebgColor; - - /// type of [Color] used to change the border color of the active checkbox - final Color activeBorderColor; - - /// type of [Color] used to change the border color of the inactive checkbox - final Color inactiveBorderColor; - - /// Called when the user checks or unchecks the checkbox. - final ValueChanged onChanged; - - ///Used to set the current state of the checkbox - final bool value; - - ///type of Widget used to change the checkbox's active icon - final Widget activeIcon; - - ///type of [Widget] used to change the checkbox's inactive icon - final Widget inactiveIcon; - - /// type of [Color] used to change the background color of the custom active checkbox only - final Color custombgColor; - - @override - _GFCheckboxListTileState createState() => _GFCheckboxListTileState(); -} - -class _GFCheckboxListTileState extends State { - bool isSelected = false; - @override - void initState() { - super.initState(); - isSelected = widget.value ?? false; - } - - void onStatusChange() { - setState(() { - isSelected = !isSelected; - }); - if (widget.onChanged != null) { - widget.onChanged(isSelected); - } - } - -// void onStatusChange() { -// if (widget.onChanged != null) { -// setState(() { -// isSelected = !isSelected; -// }); -// switch (widget.value) { -// case false: -// widget.onChanged(true); -// break; -// case true: -//// widget.onChanged(widget.tristate ? null : true); -//// break; -// default: // case null: -// widget.onChanged(isSelected); -// break; -// } -// } -//// } - @override - Widget build(BuildContext context) => InkWell( -// onTap: widget.onChanged != null ? () { widget.onChanged(isSelected); } : null, - onTap: onStatusChange, - -// onTap: (){ -// setState((){ -// isSelected = !isSelected; -// }); -// }, - child: GestureDetector( - child: GFListTile( - avatar: widget.avatar, - titleText: widget.titleText, - subTitle: widget.subTitle, - subtitleText: widget.subtitleText, - description: widget.description, - color: widget.color, - padding: widget.padding, - margin: widget.margin, - title: widget.title, - icon: GFCheckbox( - size: widget.size, - activebgColor: widget.activebgColor, -// onChanged:widget.onChanged, -// value: widget.value, - inactiveIcon: widget.inactiveIcon, - activeBorderColor: widget.activeBorderColor, - inactivebgColor: widget.inactivebgColor, - activeIcon: widget.activeIcon, - inactiveBorderColor: widget.inactiveBorderColor, - custombgColor: widget.custombgColor, - checkColor: widget.checkColor, - type: widget.type, - ), - ), - )); -// InkWell( -// onTap: onStatusChange, -// child: Container( -// constraints: const BoxConstraints(minHeight: 50), -// padding: widget.padding, -// margin: widget.margin, -// decoration: BoxDecoration( -// color: widget.color, -// borderRadius: const BorderRadius.all(Radius.circular(5)), -// ), -// child: Row( -// mainAxisAlignment: MainAxisAlignment.spaceBetween, -// children: [ -// widget.avatar ?? Container(), -// Expanded( -// child: Padding( -// padding: const EdgeInsets.symmetric(horizontal: 10), -// child: Column( -// crossAxisAlignment: CrossAxisAlignment.start, -// children: [ -// widget.titleText != null -// ? Text( -// widget.titleText, -// style: const TextStyle( -// fontSize: 17, -// fontWeight: FontWeight.w500, -// color: GFColors.DARK), -// ) -// : widget.title ?? Container(), -// widget.subtitleText != null -// ? Text( -// widget.subtitleText, -// style: TextStyle( -// fontSize: 14.5, -// color: Colors.black54, -// ), -// ) -// : widget.subTitle ?? Container(), -// widget.description ?? Container() -// ], -// ), -// ), -// ), -//// widget.icon ?? Container(), -// -// GFCheckbox( -// size: widget.size, -// activebgColor: widget.activebgColor, -// onChanged: widget.onChanged, -// value: widget.value, -// inactiveIcon: widget.inactiveIcon, -// activeBorderColor: widget.activeBorderColor, -// inactivebgColor: widget.inactivebgColor, -// activeIcon: widget.activeIcon, -// inactiveBorderColor: widget.inactiveBorderColor, -// custombgColor: widget.custombgColor, -// checkColor: widget.checkColor, -// type: widget.type, -// ), -// ], -// ), -// ), -// ); -} diff --git a/lib/components/checkbox_list_tile/gf_checkbox_list_tile.dart b/lib/components/checkbox_list_tile/gf_checkbox_list_tile.dart new file mode 100644 index 00000000..8fbc0c17 --- /dev/null +++ b/lib/components/checkbox_list_tile/gf_checkbox_list_tile.dart @@ -0,0 +1,146 @@ +import 'package:flutter/material.dart'; +import 'package:getwidget/getwidget.dart'; + +class GFCheckboxListTile extends StatelessWidget { + const GFCheckboxListTile({ + Key key, + @required this.value, + @required this.onChanged, + this.titleText, + this.subtitleText, + this.color, + this.avatar, + this.title, + this.subTitle, + this.description, + this.padding = const EdgeInsets.all(8), + this.margin = const EdgeInsets.all(16), + this.size = GFSize.MEDIUM, + this.type = GFCheckboxType.basic, + this.checkColor = GFColors.WHITE, + this.activebgColor = GFColors.PRIMARY, + this.inactivebgColor = GFColors.WHITE, + this.activeBorderColor = GFColors.WHITE, + this.inactiveBorderColor = GFColors.DARK, + this.activeIcon = const Icon( + Icons.check, + size: 20, + color: GFColors.WHITE, + ), + this.inactiveIcon = const Icon(Icons.close), + this.custombgColor = GFColors.SUCCESS, + this.selected = false, + this.autofocus = false, + }) : assert(value != null), + assert(selected != null), + assert(autofocus != null), + super(key: key); + + ///type of [String] used to pass text, alternative to title property and gets higher priority than title + final String titleText; + + ///type of [String] used to pass text, alternative to subtitle property and gets higher priority than subtitle + final String subtitleText; + + /// The GFListTile's background color. Can be given [Color] or [GFColors] + final Color color; + + /// type of [Widget] or [GFAvatar] used to create rounded user profile + final Widget avatar; + + /// The title to display inside the [GFListTile]. see [Text] + final Widget title; + + /// The subTitle to display inside the [GFListTile]. see [Text] + final Widget subTitle; + + /// The description to display inside the [GFListTile]. see [Text] + final Widget description; + + /// defines the margin of GFListTile + final EdgeInsets margin; + + /// defines the padding of GFListTile + final EdgeInsets padding; + + /// type of [GFCheckboxType] which is of four type is basic, sqaure, circular and custom + final GFCheckboxType type; + + /// type of [double] which is GFSize ie, small, medium and large and can use any double value + final double size; + + /// type pf [Color] used to change the checkcolor when the checkbox is active + final Color checkColor; + + /// type of [Color] used to change the backgroundColor of the active checkbox + final Color activebgColor; + + /// type of [Color] used to change the backgroundColor of the inactive checkbox + final Color inactivebgColor; + + /// type of [Color] used to change the border color of the active checkbox + final Color activeBorderColor; + + /// type of [Color] used to change the border color of the inactive checkbox + final Color inactiveBorderColor; + + /// Called when the user checks or unchecks the checkbox. + final ValueChanged onChanged; + + ///Used to set the current state of the checkbox + final bool value; + + ///type of Widget used to change the checkbox's active icon + final Widget activeIcon; + + ///type of [Widget] used to change the checkbox's inactive icon + final Widget inactiveIcon; + + /// type of [Color] used to change the background color of the custom active checkbox only + final Color custombgColor; + + /// To have the list tile appear selected when the checkbox is checked, pass the same value to both. + /// Normally, this property is left to its default value, false. + final bool selected; + + /// {@macro flutter.widgets.Focus.autofocus} + final bool autofocus; + + @override + Widget build(BuildContext context) => MergeSemantics( + child: GFListTile( + autofocus: autofocus, + enabled: onChanged != null, + onTap: onChanged != null + ? () { + onChanged(!value); + } + : null, + selected: selected, + avatar: avatar, + titleText: titleText, + subTitle: subTitle, + subtitleText: subtitleText, + description: description, + color: color, + padding: padding, + margin: margin, + title: title, + icon: GFCheckbox( + autofocus: autofocus, + onChanged: onChanged, + value: value, + size: size, + activebgColor: activebgColor, + inactiveIcon: inactiveIcon, + activeBorderColor: activeBorderColor, + inactivebgColor: inactivebgColor, + activeIcon: activeIcon, + inactiveBorderColor: inactiveBorderColor, + custombgColor: custombgColor, + checkColor: checkColor, + type: type, + ), + ), + ); +} diff --git a/lib/components/list_tile/gf_list_tile.dart b/lib/components/list_tile/gf_list_tile.dart index 2c503ae7..0c535fe3 100644 --- a/lib/components/list_tile/gf_list_tile.dart +++ b/lib/components/list_tile/gf_list_tile.dart @@ -16,7 +16,18 @@ class GFListTile extends StatelessWidget { this.icon, this.padding = const EdgeInsets.all(8), this.margin = const EdgeInsets.all(16), - }) : super(key: key); + this.enabled = true, + this.onTap, + this.onLongPress, + this.selected = false, + this.focusColor, + this.hoverColor, + this.focusNode, + this.autofocus = false, + }) : assert(enabled != null), + assert(selected != null), + assert(autofocus != null), + super(key: key); ///type of [String] used to pass text, alternative to title property and gets higher priority than title final String titleText; @@ -48,50 +59,98 @@ class GFListTile extends StatelessWidget { /// defines the padding of GFListTile final EdgeInsets padding; + /// Whether this list tile is interactive. + /// + /// If false, this list tile is styled with the disabled color from the + /// current [Theme] and the [onTap] and [onLongPress] callbacks are + /// inoperative. + final bool enabled; + + /// Called when the user taps this list tile. + /// + /// Inoperative if [enabled] is false. + final GestureTapCallback onTap; + + /// Called when the user long-presses on this list tile. + /// + /// Inoperative if [enabled] is false. + final GestureLongPressCallback onLongPress; + + /// If this tile is also [enabled] then icons and text are rendered with the same color. + /// + /// By default the selected color is the theme's primary color. The selected color + /// can be overridden with a [ListTileTheme]. + final bool selected; + + /// The color for the tile's [Material] when it has the input focus. + final Color focusColor; + + /// The color for the tile's [Material] when a pointer is hovering over it. + final Color hoverColor; + + /// {@macro flutter.widgets.Focus.focusNode} + final FocusNode focusNode; + + /// {@macro flutter.widgets.Focus.autofocus} + final bool autofocus; + @override - Widget build(BuildContext context) => Container( + Widget build(BuildContext context) => InkWell( + onTap: enabled ? onTap : null, + onLongPress: enabled ? onLongPress : null, + canRequestFocus: enabled, + focusNode: focusNode, + focusColor: focusColor, + hoverColor: hoverColor, + autofocus: autofocus, + child: Semantics( + selected: selected, + enabled: enabled, + child: Container( // constraints: const BoxConstraints(minHeight: 50), - padding: padding, - margin: margin, - decoration: BoxDecoration( - color: color, - borderRadius: const BorderRadius.all(Radius.circular(5)), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - avatar ?? Container(), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - titleText != null - ? Text( - titleText, - style: const TextStyle( - fontSize: 17, - fontWeight: FontWeight.w500, - color: GFColors.DARK), - ) - : title ?? Container(), - subtitleText != null - ? Text( - subtitleText, - style: const TextStyle( - fontSize: 14.5, - color: Colors.black54, - ), - ) - : subTitle ?? Container(), - description ?? Container() - ], + padding: padding, + margin: margin, + decoration: BoxDecoration( + color: color, + borderRadius: const BorderRadius.all(Radius.circular(5)), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + avatar ?? Container(), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + titleText != null + ? Text( + titleText, + style: const TextStyle( + fontSize: 17, + fontWeight: FontWeight.w500, + color: GFColors.DARK), + ) + : title ?? Container(), + subtitleText != null + ? Text( + subtitleText, + style: const TextStyle( + fontSize: 14.5, + color: Colors.black54, + ), + ) + : subTitle ?? Container(), + description ?? Container() + ], + ), + ), ), - ), + icon ?? Container(), + ], ), - icon ?? Container(), - ], + ), ), ); } diff --git a/lib/components/loader/gf_loader.dart b/lib/components/loader/gf_loader.dart index 769e6426..c398d4cf 100644 --- a/lib/components/loader/gf_loader.dart +++ b/lib/components/loader/gf_loader.dart @@ -71,7 +71,9 @@ class _GFLoaderState extends State void initState() { super.initState(); - controller = AnimationController(duration: widget.duration, vsync: this); + controller = AnimationController( + duration: widget.duration, + ); loaderanimation1 = Tween(begin: 0, end: 1).animate( CurvedAnimation( diff --git a/lib/components/progress_bar/gf_progress_bar.dart b/lib/components/progress_bar/gf_progress_bar.dart index cdd8c8e0..136f2ce3 100644 --- a/lib/components/progress_bar/gf_progress_bar.dart +++ b/lib/components/progress_bar/gf_progress_bar.dart @@ -130,7 +130,6 @@ class _GFProgressBarState extends State super.initState(); if (widget.animation) { _animationController = AnimationController( - vsync: this, duration: Duration(milliseconds: widget.animationDuration)); _animation = Tween(begin: 0, end: widget.percentage).animate(_animationController) @@ -146,7 +145,6 @@ class _GFProgressBarState extends State if (widget.animation) { circularAnimationController = AnimationController( - vsync: this, duration: Duration(milliseconds: widget.animationDuration)); circularAnimation = Tween(begin: 0, end: widget.percentage) .animate(circularAnimationController) diff --git a/lib/components/radio/gf_radio.dart b/lib/components/radio/gf_radio.dart new file mode 100644 index 00000000..f39dac92 --- /dev/null +++ b/lib/components/radio/gf_radio.dart @@ -0,0 +1,177 @@ +import 'package:flutter/material.dart'; +import 'package:getwidget/getwidget.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter/widgets.dart'; + +class GFRadio extends StatefulWidget { + const GFRadio( + {Key key, + @required this.value, + @required this.groupValue, + @required this.onChanged, + this.size = GFSize.SMALL, + this.type = GFRadioType.basic, + this.radioColor = GFColors.SUCCESS, + this.activebgColor = GFColors.WHITE, + this.inactivebgColor = GFColors.WHITE, + this.activeBorderColor = GFColors.DARK, + this.inactiveBorderColor = GFColors.DARK, + this.activeIcon = const Icon( + Icons.check, + size: 20, + color: GFColors.DARK, + ), + this.inactiveIcon = const Icon( + Icons.close, + size: 20, + color: GFColors.DARK, + ), + this.custombgColor = GFColors.SUCCESS, + this.autofocus = false, + this.focusNode, + this.toggleable = false}) + : assert(autofocus != null), + assert(toggleable != null), + super(key: key); + + /// type of [GFRadioType] which is of four type is basic, sqaure, circular and custom + final GFRadioType type; + + /// type of [double] which is GFSize ie, small, medium and large and can use any double value + final double size; + + /// type pf [Color] used to change the checkcolor when the checkbox is active + final Color radioColor; + + /// type of [Color] used to change the backgroundColor of the active checkbox + final Color activebgColor; + + /// type of [Color] used to change the backgroundColor of the inactive checkbox + final Color inactivebgColor; + + /// type of [Color] used to change the border color of the active checkbox + final Color activeBorderColor; + + /// type of [Color] used to change the border color of the inactive checkbox + final Color inactiveBorderColor; + + /// Called when the user checks or unchecks the checkbox. + final ValueChanged onChanged; + + ///type of Widget used to change the checkbox's active icon + final Widget activeIcon; + + ///type of [Widget] used to change the checkbox's inactive icon + final Widget inactiveIcon; + + /// type of [Color] used to change the background color of the custom active checkbox only + final Color custombgColor; + + /// {@macro flutter.widgets.Focus.focusNode} + final FocusNode focusNode; + + /// {@macro flutter.widgets.Focus.autofocus} + final bool autofocus; + + /// The value represented by this radio button. + final T value; + + /// The currently selected value for a group of radio buttons. Radio button is considered selected if its [value] matches the + /// [groupValue]. + final T groupValue; + + /// sets the radio value + final bool toggleable; + + @override + _GFRadioState createState() => _GFRadioState(); +} + +class _GFRadioState extends State> with TickerProviderStateMixin { + bool get enabled => widget.onChanged != null; + bool selected = false; + T groupValue; + + void onStatusChange() { + print('wer ${widget.value == widget.groupValue}'); + groupValue = widget.value; + _handleChanged(widget.value == groupValue); + } + + void _handleChanged(bool selected) { + if (selected == null) { + widget.onChanged(null); + return; + } + if (selected) { + widget.onChanged(widget.value); + } + } + + @override + Widget build(BuildContext context) { +// print('gr ${widget.value} ${widget.groupValue}'); + selected = widget.value == widget.groupValue; +// print('sel $selected'); + + return InkWell( + enableFeedback: enabled, + onTap: onStatusChange, + child: Container( + height: widget.size, + width: widget.size, + decoration: BoxDecoration( + color: selected ? widget.activebgColor : widget.inactivebgColor, + borderRadius: widget.type == GFRadioType.basic + ? BorderRadius.circular(50) + : widget.type == GFRadioType.square + ? BorderRadius.circular(0) + : BorderRadius.circular(10), + border: Border.all( + color: selected + ? widget.activeBorderColor + : widget.inactiveBorderColor)), + child: selected + ? widget.type == GFRadioType.basic || + widget.type == GFRadioType.square + ? Stack( + children: [ + Container( + alignment: Alignment.center, + ), + Container( + margin: const EdgeInsets.all(5), + alignment: Alignment.center, + width: widget.size * 0.7, + height: widget.size * 0.7, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: widget.radioColor), + ) + ], + ) + : widget.type == GFRadioType.blunt + ? Stack( + children: [ + Container( + alignment: Alignment.center, + ), + Container( + margin: const EdgeInsets.all(5), + alignment: Alignment.center, + width: widget.size * 0.8, + height: widget.size * 0.8, + decoration: BoxDecoration( + borderRadius: const BorderRadius.all( + Radius.circular(50)), + color: widget.custombgColor), + ) + ], + ) + : widget.type == GFRadioType.custom + ? widget.activeIcon + : widget.inactiveIcon + : widget.inactiveIcon)); + } +} diff --git a/lib/components/radio_list_tile/gf_radio_list_tile.dart b/lib/components/radio_list_tile/gf_radio_list_tile.dart new file mode 100644 index 00000000..6c5bade8 --- /dev/null +++ b/lib/components/radio_list_tile/gf_radio_list_tile.dart @@ -0,0 +1,206 @@ +import 'package:flutter/material.dart'; +import 'package:getwidget/getwidget.dart'; + +class GFRadioListTile extends StatelessWidget { + const GFRadioListTile({ + Key key, + @required this.value, + @required this.groupValue, + @required this.onChanged, + this.size = GFSize.SMALL, + this.type = GFRadioType.basic, + this.radioColor = GFColors.SUCCESS, + this.activebgColor = GFColors.WHITE, + this.inactivebgColor = GFColors.WHITE, + this.activeBorderColor = GFColors.DARK, + this.inactiveBorderColor = GFColors.DARK, + this.activeIcon = const Icon( + Icons.check, + size: 20, + color: GFColors.DARK, + ), + this.inactiveIcon = const Icon( + Icons.close, + size: 20, + color: GFColors.DARK, + ), + this.custombgColor = GFColors.SUCCESS, + this.autofocus = false, + this.focusNode, + this.toggleable = false, + this.titleText, + this.subtitleText, + this.color, + this.avatar, + this.title, + this.subTitle, + this.description, + this.icon, + this.padding = const EdgeInsets.all(8), + this.margin = const EdgeInsets.all(16), + this.enabled = true, + this.onTap, + this.onLongPress, + this.selected = false, + this.focusColor, + this.hoverColor, + }) : assert(autofocus != null), + assert(toggleable != null), + assert(enabled != null), + assert(selected != null), + super(key: key); + + ///type of [String] used to pass text, alternative to title property and gets higher priority than title + final String titleText; + + ///type of [String] used to pass text, alternative to subtitle property and gets higher priority than subtitle + final String subtitleText; + + /// The GFListTile's background color. Can be given [Color] or [GFColors] + final Color color; + + /// type of [Widget] or [GFAvatar] used to create rounded user profile + final Widget avatar; + + /// The title to display inside the [GFListTile]. see [Text] + final Widget title; + + /// The subTitle to display inside the [GFListTile]. see [Text] + final Widget subTitle; + + /// The description to display inside the [GFListTile]. see [Text] + final Widget description; + + /// The icon to display inside the [GFListTile]. see [Icon] + final Widget icon; + + /// defines the margin of GFListTile + final EdgeInsets margin; + + /// defines the padding of GFListTile + final EdgeInsets padding; + + /// Whether this list tile is interactive. + /// + /// If false, this list tile is styled with the disabled color from the + /// current [Theme] and the [onTap] and [onLongPress] callbacks are + /// inoperative. + final bool enabled; + + /// Called when the user taps this list tile. + /// + /// Inoperative if [enabled] is false. + final GestureTapCallback onTap; + + /// Called when the user long-presses on this list tile. + /// + /// Inoperative if [enabled] is false. + final GestureLongPressCallback onLongPress; + + /// If this tile is also [enabled] then icons and text are rendered with the same color. + /// + /// By default the selected color is the theme's primary color. The selected color + /// can be overridden with a [ListTileTheme]. + final bool selected; + + /// The color for the tile's [Material] when it has the input focus. + final Color focusColor; + + /// The color for the tile's [Material] when a pointer is hovering over it. + final Color hoverColor; + + /// {@macro flutter.widgets.Focus.focusNode} + final FocusNode focusNode; + + /// {@macro flutter.widgets.Focus.autofocus} + final bool autofocus; + + /// type of [GFRadioType] which is of four type is basic, sqaure, circular and custom + final GFRadioType type; + + /// type of [double] which is GFSize ie, small, medium and large and can use any double value + final double size; + + /// type pf [Color] used to change the checkcolor when the checkbox is active + final Color radioColor; + + /// type of [Color] used to change the backgroundColor of the active checkbox + final Color activebgColor; + + /// type of [Color] used to change the backgroundColor of the inactive checkbox + final Color inactivebgColor; + + /// type of [Color] used to change the border color of the active checkbox + final Color activeBorderColor; + + /// type of [Color] used to change the border color of the inactive checkbox + final Color inactiveBorderColor; + + /// Called when the user checks or unchecks the checkbox. + final ValueChanged onChanged; + + ///type of Widget used to change the checkbox's active icon + final Widget activeIcon; + + ///type of [Widget] used to change the checkbox's inactive icon + final Widget inactiveIcon; + + /// type of [Color] used to change the background color of the custom active checkbox only + final Color custombgColor; + + /// The value represented by this radio button. + final T value; + + /// The currently selected value for a group of radio buttons. Radio button is considered selected if its [value] matches the + /// [groupValue]. + final T groupValue; + + /// sets the radio value + final bool toggleable; + + /// Whether this radio button is checked. To control this value, set [value] and [groupValue] appropriately. + bool get checked => value == groupValue; + + @override + Widget build(BuildContext context) => MergeSemantics( + child: GFListTile( + autofocus: autofocus, + enabled: onChanged != null, + onTap: onChanged != null + ? () { + if (toggleable && checked) { + onChanged(null); + return; + } + if (!checked) { + onChanged(value); + } + } + : null, + selected: selected, + avatar: avatar, + titleText: titleText, + subTitle: subTitle, + subtitleText: subtitleText, + description: description, + color: color, + padding: padding, + margin: margin, + title: title, + icon: GFRadio( + autofocus: autofocus, + onChanged: onChanged, + value: value, + groupValue: groupValue, + size: size, + activebgColor: activebgColor, + inactiveIcon: inactiveIcon, + activeBorderColor: activeBorderColor, + inactivebgColor: inactivebgColor, + activeIcon: activeIcon, + inactiveBorderColor: inactiveBorderColor, + custombgColor: custombgColor, + ), + ), + ); +} diff --git a/lib/components/radiobutton/gf_radio_button.dart b/lib/components/radiobutton/gf_radio_button.dart deleted file mode 100644 index 350215d1..00000000 --- a/lib/components/radiobutton/gf_radio_button.dart +++ /dev/null @@ -1,149 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:getwidget/getwidget.dart'; - -class GFRadioButton extends StatefulWidget { - const GFRadioButton( - {Key key, - this.size = GFSize.SMALL, - this.type = GFRadioButtonType.basic, - this.radioColor = GFColors.SUCCESS, - this.activebgColor = GFColors.WHITE, - this.inactivebgColor = GFColors.WHITE, - this.activeBorderColor = GFColors.DARK, - this.inactiveBorderColor = GFColors.DARK, - this.onChanged, - this.value, - this.activeIcon = const Icon( - Icons.check, - size: 20, - color: GFColors.DARK, - ), - this.inactiveIcon = const Icon( - Icons.close, - size: 20, - color: GFColors.DARK, - ), - this.custombgColor = GFColors.SUCCESS, - this.groupValue}) - : super(key: key); - - /// type of [GFRadioButtonType] which is of four type is basic, sqaure, circular and custom - final GFRadioButtonType type; - - /// type of [double] which is GFSize ie, small, medium and large and can use any double value - final double size; - - // type pf [Color] used to change the checkcolor when the checkbox is active - final Color radioColor; - - /// type of [Color] used to change the backgroundColor of the active checkbox - final Color activebgColor; - - /// type of [Color] used to change the backgroundColor of the inactive checkbox - final Color inactivebgColor; - - /// type of [Color] used to change the border color of the active checkbox - final Color activeBorderColor; - - /// type of [Color] used to change the border color of the inactive checkbox - final Color inactiveBorderColor; - - /// Called when the user checks or unchecks the checkbox. - final ValueChanged onChanged; - - ///Used to set the current state of the checkbox - final bool value; - - ///type of Widget used to change the checkbox's active icon - final Widget activeIcon; - - ///type of [Widget] used to change the checkbox's inactive icon - final Widget inactiveIcon; - - /// type of [Color] used to change the background color of the custom active checkbox only - final Color custombgColor; - - final bool groupValue; - - @override - _GFRadioButtonState createState() => _GFRadioButtonState(); -} - -class _GFRadioButtonState extends State { -// - - bool isSelected = false; - - @override - void initState() { - super.initState(); - isSelected = widget.value == widget.groupValue ?? false; - } - - void onStatusChange() { - setState(() { - isSelected = !isSelected; - }); - if (widget.onChanged != null) { - widget.onChanged(isSelected); - } - } - - @override - Widget build(BuildContext context) => InkWell( - onTap: onStatusChange, - child: Container( - height: widget.size, - width: widget.size, - decoration: BoxDecoration( - color: isSelected ? widget.activebgColor : widget.inactivebgColor, - borderRadius: widget.type == GFRadioButtonType.basic - ? BorderRadius.circular(50) - : widget.type == GFRadioButtonType.square - ? BorderRadius.circular(0) - : BorderRadius.circular(10), - border: Border.all( - color: isSelected - ? widget.activeBorderColor - : widget.inactiveBorderColor)), - child: isSelected - ? widget.type == GFRadioButtonType.basic || - widget.type == GFRadioButtonType.square - ? Stack( - children: [ - Container( - alignment: Alignment.center, - ), - Container( - margin: const EdgeInsets.all(5), - alignment: Alignment.center, - width: widget.size * 0.7, - height: widget.size * 0.7, - decoration: BoxDecoration( - shape: BoxShape.circle, color: widget.radioColor), - ) - ], - ) - : widget.type == GFRadioButtonType.blunt - ? Stack( - children: [ - Container( - alignment: Alignment.center, - ), - Container( - margin: const EdgeInsets.all(5), - alignment: Alignment.center, - width: widget.size * 0.8, - height: widget.size * 0.8, - decoration: BoxDecoration( - borderRadius: const BorderRadius.all( - Radius.circular(50)), - color: widget.custombgColor), - ) - ], - ) - : widget.type == GFRadioButtonType.custom - ? widget.activeIcon - : widget.inactiveIcon - : widget.inactiveIcon)); -} diff --git a/lib/components/shimmer/gf_shimmer.dart b/lib/components/shimmer/gf_shimmer.dart index 623134d8..66737f7f 100644 --- a/lib/components/shimmer/gf_shimmer.dart +++ b/lib/components/shimmer/gf_shimmer.dart @@ -65,7 +65,7 @@ class _GFShimmerState extends State void initState() { super.initState(); _count = 0; - _controller = AnimationController(vsync: this, duration: widget.duration) + _controller = AnimationController(duration: widget.duration) ..addStatusListener((AnimationStatus status) { if (status != AnimationStatus.completed) { return; diff --git a/lib/components/toast/gf_toast.dart b/lib/components/toast/gf_toast.dart index 99309d9d..f406616b 100644 --- a/lib/components/toast/gf_toast.dart +++ b/lib/components/toast/gf_toast.dart @@ -71,7 +71,6 @@ class _GFToastState extends State with TickerProviderStateMixin { void initState() { animationController = AnimationController( duration: widget.duration, - vsync: this, ); animation = CurvedAnimation( parent: animationController, @@ -81,7 +80,6 @@ class _GFToastState extends State with TickerProviderStateMixin { if (mounted) { animationController.forward(); fadeanimationController = AnimationController( - vsync: this, duration: widget.animationDuration, )..addListener(() => setState(() {})); fadeanimation = Tween( diff --git a/lib/components/toggle/gf_toggle.dart b/lib/components/toggle/gf_toggle.dart index 1fee30c1..aef51bcb 100644 --- a/lib/components/toggle/gf_toggle.dart +++ b/lib/components/toggle/gf_toggle.dart @@ -89,7 +89,7 @@ class _GFToggleState extends State with TickerProviderStateMixin { setState(() { isOn = widget.value ?? false; }); - controller = AnimationController(vsync: this, duration: widget.duration); + controller = AnimationController(duration: widget.duration); offset = (isOn ? Tween( begin: const Offset(1, 0), diff --git a/lib/getwidget.dart b/lib/getwidget.dart index ed827ee1..651ec4e4 100644 --- a/lib/getwidget.dart +++ b/lib/getwidget.dart @@ -1,43 +1,47 @@ library getwidget; //exports components -export 'package:getwidget/components/alert/gf_alert.dart'; export 'package:getwidget/components/accordian/gf_accordian.dart'; +export 'package:getwidget/components/alert/gf_alert.dart'; export 'package:getwidget/components/appbar/gf_appbar.dart'; export 'package:getwidget/components/avatar/gf_avatar.dart'; export 'package:getwidget/components/badge/gf_badge.dart'; export 'package:getwidget/components/badge/gf_button_badge.dart'; export 'package:getwidget/components/badge/gf_icon_badge.dart'; +export 'package:getwidget/components/border/gf_border.dart'; +export 'package:getwidget/components/bottom_sheet/gf_bottom_sheet.dart'; export 'package:getwidget/components/button/gf_button.dart'; +export 'package:getwidget/components/button/gf_button_bar.dart'; export 'package:getwidget/components/button/gf_icon_button.dart'; export 'package:getwidget/components/button/gf_social_button.dart'; -export 'package:getwidget/components/button/gf_button_bar.dart'; export 'package:getwidget/components/card/gf_card.dart'; export 'package:getwidget/components/carousel/gf_carousel.dart'; export 'package:getwidget/components/carousel/gf_items_carousel.dart'; +export 'package:getwidget/components/checkbox/gf_checkbox.dart'; +export 'package:getwidget/components/checkbox_list_tile/gf_checkbox_list_tile.dart'; export 'package:getwidget/components/drawer/gf_drawer.dart'; export 'package:getwidget/components/drawer/gf_drawer_header.dart'; +export 'package:getwidget/components/floating_widget/gf_floating_widget.dart'; export 'package:getwidget/components/image/gf_image_overlay.dart'; export 'package:getwidget/components/list_tile/gf_list_tile.dart'; +export 'package:getwidget/components/loader/gf_loader.dart'; +export 'package:getwidget/components/progress_bar/gf_progress_bar.dart'; +export 'package:getwidget/components/radio/gf_radio.dart'; +export 'package:getwidget/components/radio_list_tile/gf_radio_list_tile.dart'; +export 'package:getwidget/components/rating/gf_rating.dart'; export 'package:getwidget/components/search_bar/gf_search_bar.dart'; +export 'package:getwidget/components/shimmer/gf_shimmer.dart'; +export 'package:getwidget/components/slidable/gf_slidable.dart'; +export 'package:getwidget/components/tabs/gf_segment_tabs.dart'; export 'package:getwidget/components/tabs/gf_tabbar.dart'; export 'package:getwidget/components/tabs/gf_tabbar_view.dart'; export 'package:getwidget/components/tabs/gf_tabs.dart'; -export 'package:getwidget/components/tabs/gf_segment_tabs.dart'; -export 'package:getwidget/components/floating_widget/gf_floating_widget.dart'; export 'package:getwidget/components/toast/gf_toast.dart'; export 'package:getwidget/components/toggle/gf_toggle.dart'; export 'package:getwidget/components/typography/gf_typography.dart'; -export 'package:getwidget/components/rating/gf_rating.dart'; -export 'package:getwidget/components/slidable/gf_slidable.dart'; -export 'package:getwidget/components/shimmer/gf_shimmer.dart'; -export 'package:getwidget/components/loader/gf_loader.dart'; -export 'package:getwidget/components/progress_bar/gf_progress_bar.dart'; -export 'package:getwidget/components/checkbox/gf_checkbox.dart'; -export 'package:getwidget/components/checkboxListTile/gf_checkbox_list_tile.dart'; -export 'package:getwidget/components/radiobutton/gf_radio_button.dart'; -// exports shape, color, position, size, types, direction + + export 'colors/gf_color.dart'; export 'direction/gf_shimmer_direction.dart'; export 'position/gf_position.dart'; @@ -47,6 +51,7 @@ export 'shape/gf_button_shape.dart'; export 'shape/gf_icon_button_shape.dart'; export 'size/gf_size.dart'; export 'types/gf_alert_type.dart'; +export 'types/gf_border_type.dart'; export 'types/gf_button_type.dart'; export 'types/gf_checkbox_type.dart'; export 'types/gf_loader_type.dart'; diff --git a/lib/types/gf_animation_type.dart b/lib/types/gf_animation_type.dart new file mode 100644 index 00000000..7a97b55e --- /dev/null +++ b/lib/types/gf_animation_type.dart @@ -0,0 +1,9 @@ +enum GFAnimationType { + align, + size, + container, + rotateTransition, + scaleTransition, + slideTransition, + textStyle +} diff --git a/lib/types/gf_border_type.dart b/lib/types/gf_border_type.dart new file mode 100644 index 00000000..bea0b2a9 --- /dev/null +++ b/lib/types/gf_border_type.dart @@ -0,0 +1 @@ +enum GFBorderType { Circle, RRect, Rect, Oval } diff --git a/lib/types/gf_radio_type.dart b/lib/types/gf_radio_type.dart index 836d06cb..61fab9b0 100644 --- a/lib/types/gf_radio_type.dart +++ b/lib/types/gf_radio_type.dart @@ -1 +1 @@ -enum GFRadioButtonType { basic, square, custom, blunt } +enum GFRadioType { basic, square, custom, blunt } diff --git a/pubspec.lock b/pubspec.lock index 67a7df16..e69de29b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,188 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - archive: - dependency: transitive - description: - name: archive - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.11" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.2" - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.2" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.11" - convert: - dependency: transitive - description: - name: convert - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - image: - dependency: transitive - description: - name: image - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.4" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - petitparser: - dependency: transitive - description: - name: petitparser - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.5" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.11" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" - xml: - dependency: transitive - description: - name: xml - url: "https://pub.dartlang.org" - source: hosted - version: "3.5.0" -sdks: - dart: ">=2.4.0 <3.0.0"