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.

244 lines
9.2KB

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