You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

221 lines
8.4KB

  1. import 'package:farm_tpf/utils/const_color.dart';
  2. import 'package:flutter/material.dart';
  3. import 'home_drawer.dart';
  4. class DrawerUserController extends StatefulWidget {
  5. const DrawerUserController({
  6. Key key,
  7. this.drawerWidth = 250,
  8. this.onDrawerCall,
  9. this.screenView,
  10. this.animatedIconData = AnimatedIcons.arrow_menu,
  11. this.menuView,
  12. this.drawerIsOpen,
  13. this.screenIndex,
  14. }) : super(key: key);
  15. final double drawerWidth;
  16. final Function(DrawerIndex) onDrawerCall;
  17. final Widget screenView;
  18. final Function(bool) drawerIsOpen;
  19. final AnimatedIconData animatedIconData;
  20. final Widget menuView;
  21. final DrawerIndex screenIndex;
  22. @override
  23. _DrawerUserControllerState createState() => _DrawerUserControllerState();
  24. }
  25. class _DrawerUserControllerState extends State<DrawerUserController>
  26. with TickerProviderStateMixin {
  27. ScrollController scrollController;
  28. AnimationController iconAnimationController;
  29. AnimationController animationController;
  30. double scrolloffset = 0.0;
  31. @override
  32. void initState() {
  33. animationController = AnimationController(
  34. duration: const Duration(milliseconds: 2000), vsync: this);
  35. iconAnimationController = AnimationController(
  36. vsync: this, duration: const Duration(milliseconds: 0));
  37. iconAnimationController
  38. ..animateTo(1.0,
  39. duration: const Duration(milliseconds: 0),
  40. curve: Curves.fastOutSlowIn);
  41. scrollController =
  42. ScrollController(initialScrollOffset: widget.drawerWidth);
  43. scrollController
  44. ..addListener(() {
  45. if (scrollController.offset <= 0) {
  46. if (scrolloffset != 1.0) {
  47. setState(() {
  48. scrolloffset = 1.0;
  49. try {
  50. widget.drawerIsOpen(true);
  51. } catch (_) {}
  52. });
  53. }
  54. iconAnimationController.animateTo(0.0,
  55. duration: const Duration(milliseconds: 0),
  56. curve: Curves.fastOutSlowIn);
  57. } else if (scrollController.offset > 0 &&
  58. scrollController.offset < widget.drawerWidth) {
  59. iconAnimationController.animateTo(
  60. (scrollController.offset * 100 / (widget.drawerWidth)) / 100,
  61. duration: const Duration(milliseconds: 0),
  62. curve: Curves.fastOutSlowIn);
  63. } else if (scrollController.offset <= widget.drawerWidth) {
  64. if (scrolloffset != 0.0) {
  65. setState(() {
  66. scrolloffset = 0.0;
  67. try {
  68. widget.drawerIsOpen(false);
  69. } catch (_) {}
  70. });
  71. }
  72. iconAnimationController.animateTo(1.0,
  73. duration: const Duration(milliseconds: 0),
  74. curve: Curves.fastOutSlowIn);
  75. }
  76. });
  77. WidgetsBinding.instance.addPostFrameCallback((_) => getInitState());
  78. super.initState();
  79. }
  80. Future<bool> getInitState() async {
  81. scrollController.jumpTo(
  82. widget.drawerWidth,
  83. );
  84. return true;
  85. }
  86. @override
  87. Widget build(BuildContext context) {
  88. return Scaffold(
  89. backgroundColor: COLOR_CONST.WHITE,
  90. body: SingleChildScrollView(
  91. controller: scrollController,
  92. scrollDirection: Axis.horizontal,
  93. physics: const PageScrollPhysics(parent: ClampingScrollPhysics()),
  94. child: SizedBox(
  95. height: MediaQuery.of(context).size.height,
  96. width: MediaQuery.of(context).size.width + widget.drawerWidth,
  97. //we use with as screen width and add drawerWidth (from navigation_home_screen)
  98. child: Row(
  99. children: <Widget>[
  100. SizedBox(
  101. width: widget.drawerWidth,
  102. //we divided first drawer Width with HomeDrawer and second full-screen Width with all home screen, we called screen View
  103. height: MediaQuery.of(context).size.height,
  104. child: AnimatedBuilder(
  105. animation: iconAnimationController,
  106. builder: (BuildContext context, Widget child) {
  107. return Transform(
  108. //transform we use for the stable drawer we, not need to move with scroll view
  109. transform: Matrix4.translationValues(
  110. scrollController.offset, 0.0, 0.0),
  111. child: HomeDrawer(
  112. screenIndex: widget.screenIndex == null
  113. ? DrawerIndex.Home
  114. : widget.screenIndex,
  115. iconAnimationController: iconAnimationController,
  116. callBackIndex: (DrawerIndex indexType) {
  117. onDrawerClick();
  118. try {
  119. widget.onDrawerCall(indexType);
  120. } catch (e) {}
  121. },
  122. ),
  123. );
  124. },
  125. ),
  126. ),
  127. SizedBox(
  128. width: MediaQuery.of(context).size.width,
  129. height: MediaQuery.of(context).size.height,
  130. //full-screen Width with widget.screenView
  131. child: Container(
  132. decoration: BoxDecoration(
  133. color: COLOR_CONST.WHITE,
  134. boxShadow: <BoxShadow>[
  135. BoxShadow(color: COLOR_CONST.GRAY1, blurRadius: 24),
  136. ],
  137. ),
  138. child: Stack(
  139. children: <Widget>[
  140. //this IgnorePointer we use as touch(user Interface) widget.screen View, for example scrolloffset == 1 means drawer is close we just allow touching all widget.screen View
  141. IgnorePointer(
  142. ignoring: scrolloffset == 1 || false,
  143. child: widget.screenView,
  144. ),
  145. //alternative touch(user Interface) for widget.screen, for example, drawer is close we need to tap on a few home screen area and close the drawer
  146. if (scrolloffset == 1.0)
  147. InkWell(
  148. onTap: () {
  149. onDrawerClick();
  150. },
  151. ),
  152. // this just menu and arrow icon animation
  153. Padding(
  154. padding: EdgeInsets.only(
  155. top: MediaQuery.of(context).padding.top + 8,
  156. left: 8),
  157. child: SizedBox(
  158. width: AppBar().preferredSize.height - 8,
  159. height: AppBar().preferredSize.height - 8,
  160. child: Material(
  161. color: Colors.transparent,
  162. child: InkWell(
  163. borderRadius: BorderRadius.circular(
  164. AppBar().preferredSize.height),
  165. child: Center(
  166. // if you use your own menu view UI you add form initialization
  167. child: widget.menuView != null
  168. ? widget.menuView
  169. : AnimatedIcon(
  170. icon: widget.animatedIconData != null
  171. ? widget.animatedIconData
  172. : AnimatedIcons.arrow_menu,
  173. progress: iconAnimationController),
  174. ),
  175. onTap: () {
  176. FocusScope.of(context)
  177. .requestFocus(FocusNode());
  178. onDrawerClick();
  179. },
  180. ),
  181. ),
  182. ),
  183. ),
  184. ],
  185. ),
  186. ),
  187. ),
  188. ],
  189. ),
  190. ),
  191. ),
  192. );
  193. }
  194. void onDrawerClick() {
  195. //if scrollcontroller.offset != 0.0 then we set to closed the drawer(with animation to offset zero position) if is not 1 then open the drawer
  196. if (scrollController.offset != 0.0) {
  197. scrollController.animateTo(
  198. 0.0,
  199. duration: const Duration(milliseconds: 400),
  200. curve: Curves.fastOutSlowIn,
  201. );
  202. } else {
  203. scrollController.animateTo(
  204. widget.drawerWidth,
  205. duration: const Duration(milliseconds: 400),
  206. curve: Curves.fastOutSlowIn,
  207. );
  208. }
  209. }
  210. }