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.

268 lines
9.0KB

  1. import 'package:farm_tpf/data/repository/repository.dart';
  2. import 'package:farm_tpf/models/index.dart';
  3. import 'package:farm_tpf/presentation/custom_widgets/bottom_loader.dart';
  4. import 'package:farm_tpf/presentation/custom_widgets/loading_list_page.dart';
  5. import 'package:farm_tpf/presentation/screens/actions/other/sc_edit_action_other.dart';
  6. import 'package:farm_tpf/presentation/screens/plot/sc_plot.dart';
  7. import 'package:farm_tpf/presentation/screens/plot_detail/bloc/plot_detail_bloc.dart';
  8. import 'package:farm_tpf/utils/const_color.dart';
  9. import 'package:farm_tpf/utils/const_string.dart';
  10. import 'package:flutter/material.dart';
  11. import 'package:flutter_bloc/flutter_bloc.dart';
  12. import 'package:farm_tpf/utils/formatter.dart';
  13. class PlotActionScreen extends StatefulWidget {
  14. final int cropId;
  15. PlotActionScreen({@required this.cropId});
  16. @override
  17. _PlotActionScreenState createState() => _PlotActionScreenState();
  18. }
  19. class _PlotActionScreenState extends State<PlotActionScreen> {
  20. List<ActionType> actions = new List<ActionType>();
  21. ScrollController _scrollController;
  22. @override
  23. void initState() {
  24. super.initState();
  25. _scrollController = ScrollController()..addListener(() => setState(() {}));
  26. _initActionButtons();
  27. }
  28. _initActionButtons() {
  29. actions.add(ActionType(plot_action_nursery, null, PlotListScreen()));
  30. actions.add(ActionType(plot_action_plant, null, null));
  31. actions.add(ActionType(plot_action_crop_status, null, null));
  32. actions.add(ActionType(plot_action_environment_update, null, null));
  33. actions.add(ActionType(plot_action_dung, null, null));
  34. actions.add(ActionType(plot_action_spraying, null, null));
  35. actions.add(ActionType(plot_action_disease, null, null));
  36. actions.add(ActionType(plot_action_use_water, null, null));
  37. actions.add(ActionType(plot_action_other, null, EditActionOtherScreen()));
  38. actions.add(ActionType(plot_action_harvest, null, null));
  39. actions.add(ActionType(plot_action_finish, null, null));
  40. }
  41. Widget _createActionButtons(ActionType actionType) {
  42. return GestureDetector(
  43. onTap: () {
  44. Navigator.of(context).push(
  45. MaterialPageRoute(builder: (context) => actionType.listScreen));
  46. },
  47. child: Container(
  48. height: 75,
  49. margin: EdgeInsets.all(4.0),
  50. padding: EdgeInsets.all(0.0),
  51. decoration: BoxDecoration(
  52. color: COLOR_CONST.WHITE,
  53. borderRadius: BorderRadius.only(
  54. topLeft: Radius.circular(8.0),
  55. bottomLeft: Radius.circular(8.0),
  56. bottomRight: Radius.circular(8.0),
  57. topRight: Radius.circular(8.0)),
  58. boxShadow: <BoxShadow>[
  59. BoxShadow(
  60. color: COLOR_CONST.GRAY1.withOpacity(0.2),
  61. offset: Offset(1.1, 1.1),
  62. blurRadius: 10.0),
  63. ],
  64. ),
  65. child: Stack(
  66. children: <Widget>[
  67. Positioned(
  68. top: -10,
  69. right: -3,
  70. child: (actionType.addScreen == null)
  71. ? Container()
  72. : IconButton(
  73. icon: Icon(
  74. Icons.add_circle,
  75. size: 40,
  76. color: Colors.green,
  77. ),
  78. onPressed: () {
  79. Navigator.of(context).push(MaterialPageRoute(
  80. builder: (context) => actionType.addScreen));
  81. })),
  82. Positioned.fill(
  83. child: Align(
  84. alignment: Alignment.center,
  85. child: Text(
  86. actionType.actionName,
  87. textAlign: TextAlign.center,
  88. style: TextStyle(
  89. fontWeight: FontWeight.w400,
  90. fontSize: 13,
  91. color: COLOR_CONST.BLACK2,
  92. ),
  93. )),
  94. ),
  95. ],
  96. ),
  97. ));
  98. }
  99. bool _showTitle(BuildContext context) {
  100. var kExpandedHeight = MediaQuery.of(context).size.width * 1.125 + 32;
  101. return _scrollController.hasClients &&
  102. _scrollController.offset > kExpandedHeight - kToolbarHeight;
  103. }
  104. @override
  105. Widget build(BuildContext context) {
  106. return NestedScrollView(
  107. controller: _scrollController,
  108. headerSliverBuilder: (context, innerBoxScrolled) => [
  109. SliverAppBar(
  110. floating: false,
  111. pinned: true,
  112. backgroundColor: Colors.white,
  113. leading: Container(),
  114. title: _showTitle(context) ? Text(plot_detail_title) : null,
  115. //Height flexibleSpace : WidthScreen /2 * 6/16 * 6(row) + 8(space) *4
  116. expandedHeight: MediaQuery.of(context).size.width * 1.125 + 32,
  117. flexibleSpace: _showTitle(context)
  118. ? null
  119. : FlexibleSpaceBar(
  120. centerTitle: true,
  121. title: GridView.count(
  122. shrinkWrap: true,
  123. crossAxisCount: 2,
  124. childAspectRatio: 16 / 6,
  125. children: actions.map(
  126. (item) {
  127. return _createActionButtons(item);
  128. },
  129. ).toList()),
  130. ),
  131. ),
  132. SliverList(
  133. delegate: SliverChildListDelegate([
  134. Container(
  135. alignment: Alignment.center,
  136. child: _showTitle(context)
  137. ? Text("")
  138. : Text(
  139. plot_detail_title,
  140. style: TextStyle(
  141. fontSize: 20, fontWeight: FontWeight.normal),
  142. ))
  143. ]))
  144. ],
  145. body: BlocProvider(
  146. create: (context) => PlotDetailBloc(repository: Repository())
  147. ..add(DataFetched(widget.cropId)),
  148. child: HoldInfinityWidget(
  149. cropId: widget.cropId,
  150. ),
  151. ),
  152. );
  153. }
  154. }
  155. class HoldInfinityWidget extends StatelessWidget {
  156. final int cropId;
  157. HoldInfinityWidget({@required this.cropId});
  158. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  159. @override
  160. Widget build(BuildContext context) {
  161. return Scaffold(key: _scaffoldKey, body: InfinityView(cropId: cropId));
  162. }
  163. }
  164. class InfinityView extends StatefulWidget {
  165. final int cropId;
  166. InfinityView({@required this.cropId});
  167. @override
  168. _InfinityViewState createState() => _InfinityViewState();
  169. }
  170. class _InfinityViewState extends State<InfinityView> {
  171. final _scrollController = ScrollController();
  172. final _scrollThreshold = 250.0;
  173. PlotDetailBloc _plotDetailBloc;
  174. @override
  175. void initState() {
  176. _scrollController.addListener(() {
  177. final maxScroll = _scrollController.position.maxScrollExtent;
  178. final currentScroll = _scrollController.position.pixels;
  179. if (maxScroll - currentScroll < _scrollThreshold) {
  180. _plotDetailBloc.add(DataFetched(widget.cropId));
  181. }
  182. });
  183. _plotDetailBloc = BlocProvider.of<PlotDetailBloc>(context);
  184. super.initState();
  185. }
  186. @override
  187. Widget build(BuildContext context) {
  188. return BlocBuilder<PlotDetailBloc, PlotDetailState>(
  189. builder: (context, state) {
  190. if (state is PlotDetailFailure) {
  191. return Center(child: Text(state.errorString));
  192. }
  193. if (state is PlotDetailSuccess) {
  194. if (state.items.isEmpty) {
  195. return Center(child: Text(label_list_empty));
  196. }
  197. return RefreshIndicator(
  198. child: ListView.builder(
  199. physics: AlwaysScrollableScrollPhysics(),
  200. itemBuilder: (BuildContext context, int index) {
  201. return index >= state.items.length
  202. ? BottomLoader()
  203. : ItemInfinityWidget(item: state.items[index]);
  204. },
  205. itemCount: state.hasReachedMax
  206. ? state.items.length
  207. : state.items.length + 1,
  208. controller: _scrollController,
  209. ),
  210. onRefresh: () async {
  211. _plotDetailBloc.add(OnRefresh(widget.cropId));
  212. });
  213. }
  214. return Center(
  215. child: LoadingListPage(),
  216. );
  217. },
  218. );
  219. }
  220. @override
  221. void dispose() {
  222. _scrollController.dispose();
  223. super.dispose();
  224. }
  225. }
  226. class ItemInfinityWidget extends StatelessWidget {
  227. final HistoryAction item;
  228. const ItemInfinityWidget({Key key, @required this.item}) : super(key: key);
  229. @override
  230. Widget build(BuildContext context) {
  231. return GestureDetector(
  232. child: Card(
  233. child: ListTile(
  234. title: Text(item.activityTypeName),
  235. subtitle: Text(item.executeDate.format_DDMMYY_HHmm()),
  236. ),
  237. ),
  238. onTap: () {});
  239. }
  240. }
  241. class ActionType {
  242. Widget addScreen;
  243. Widget listScreen;
  244. String actionName;
  245. ActionType(String actionName, Widget addScreen, Widget listScreen) {
  246. this.actionName = actionName;
  247. this.addScreen = addScreen;
  248. this.listScreen = listScreen;
  249. }
  250. }