import 'package:farm_tpf/data/repository/repository.dart'; import 'package:farm_tpf/models/index.dart'; import 'package:farm_tpf/presentation/custom_widgets/bottom_loader.dart'; import 'package:farm_tpf/presentation/custom_widgets/loading_list_page.dart'; import 'package:farm_tpf/presentation/screens/actions/other/sc_edit_action_other.dart'; import 'package:farm_tpf/presentation/screens/plot/sc_plot.dart'; import 'package:farm_tpf/presentation/screens/plot_detail/bloc/plot_detail_bloc.dart'; import 'package:farm_tpf/utils/const_color.dart'; import 'package:farm_tpf/utils/const_string.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:farm_tpf/utils/formatter.dart'; class PlotActionScreen extends StatefulWidget { final int cropId; PlotActionScreen({@required this.cropId}); @override _PlotActionScreenState createState() => _PlotActionScreenState(); } class _PlotActionScreenState extends State { List actions = new List(); ScrollController _scrollController; @override void initState() { super.initState(); _scrollController = ScrollController()..addListener(() => setState(() {})); _initActionButtons(); } _initActionButtons() { actions.add(ActionType(plot_action_nursery, null, PlotListScreen())); actions.add(ActionType(plot_action_plant, null, null)); actions.add(ActionType(plot_action_crop_status, null, null)); actions.add(ActionType(plot_action_environment_update, null, null)); actions.add(ActionType(plot_action_dung, null, null)); actions.add(ActionType(plot_action_spraying, null, null)); actions.add(ActionType(plot_action_disease, null, null)); actions.add(ActionType(plot_action_use_water, null, null)); actions.add(ActionType(plot_action_other, null, EditActionOtherScreen())); actions.add(ActionType(plot_action_harvest, null, null)); actions.add(ActionType(plot_action_finish, null, null)); } Widget _createActionButtons(ActionType actionType) { return GestureDetector( onTap: () { Navigator.of(context).push( MaterialPageRoute(builder: (context) => actionType.listScreen)); }, child: Container( height: 75, margin: EdgeInsets.all(4.0), padding: EdgeInsets.all(0.0), decoration: BoxDecoration( color: COLOR_CONST.WHITE, borderRadius: BorderRadius.only( topLeft: Radius.circular(8.0), bottomLeft: Radius.circular(8.0), bottomRight: Radius.circular(8.0), topRight: Radius.circular(8.0)), boxShadow: [ BoxShadow( color: COLOR_CONST.GRAY1.withOpacity(0.2), offset: Offset(1.1, 1.1), blurRadius: 10.0), ], ), child: Stack( children: [ Positioned( top: -10, right: -3, child: (actionType.addScreen == null) ? Container() : IconButton( icon: Icon( Icons.add_circle, size: 40, color: Colors.green, ), onPressed: () { Navigator.of(context).push(MaterialPageRoute( builder: (context) => actionType.addScreen)); })), Positioned.fill( child: Align( alignment: Alignment.center, child: Text( actionType.actionName, textAlign: TextAlign.center, style: TextStyle( fontWeight: FontWeight.w400, fontSize: 13, color: COLOR_CONST.BLACK2, ), )), ), ], ), )); } bool _showTitle(BuildContext context) { var kExpandedHeight = MediaQuery.of(context).size.width * 1.125 + 32; return _scrollController.hasClients && _scrollController.offset > kExpandedHeight - kToolbarHeight; } @override Widget build(BuildContext context) { return NestedScrollView( controller: _scrollController, headerSliverBuilder: (context, innerBoxScrolled) => [ SliverAppBar( floating: false, pinned: true, backgroundColor: Colors.white, leading: Container(), title: _showTitle(context) ? Text(plot_detail_title) : null, //Height flexibleSpace : WidthScreen /2 * 6/16 * 6(row) + 8(space) *4 expandedHeight: MediaQuery.of(context).size.width * 1.125 + 32, flexibleSpace: _showTitle(context) ? null : FlexibleSpaceBar( centerTitle: true, title: GridView.count( shrinkWrap: true, crossAxisCount: 2, childAspectRatio: 16 / 6, children: actions.map( (item) { return _createActionButtons(item); }, ).toList()), ), ), SliverList( delegate: SliverChildListDelegate([ Container( alignment: Alignment.center, child: _showTitle(context) ? Text("") : Text( plot_detail_title, style: TextStyle( fontSize: 20, fontWeight: FontWeight.normal), )) ])) ], body: BlocProvider( create: (context) => PlotDetailBloc(repository: Repository()) ..add(DataFetched(widget.cropId)), child: HoldInfinityWidget( cropId: widget.cropId, ), ), ); } } class HoldInfinityWidget extends StatelessWidget { final int cropId; HoldInfinityWidget({@required this.cropId}); final GlobalKey _scaffoldKey = new GlobalKey(); @override Widget build(BuildContext context) { return Scaffold(key: _scaffoldKey, body: InfinityView(cropId: cropId)); } } class InfinityView extends StatefulWidget { final int cropId; InfinityView({@required this.cropId}); @override _InfinityViewState createState() => _InfinityViewState(); } class _InfinityViewState extends State { final _scrollController = ScrollController(); final _scrollThreshold = 250.0; PlotDetailBloc _plotDetailBloc; @override void initState() { _scrollController.addListener(() { final maxScroll = _scrollController.position.maxScrollExtent; final currentScroll = _scrollController.position.pixels; if (maxScroll - currentScroll < _scrollThreshold) { _plotDetailBloc.add(DataFetched(widget.cropId)); } }); _plotDetailBloc = BlocProvider.of(context); super.initState(); } @override Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { if (state is PlotDetailFailure) { return Center(child: Text(state.errorString)); } if (state is PlotDetailSuccess) { if (state.items.isEmpty) { return Center(child: Text(label_list_empty)); } return RefreshIndicator( child: ListView.builder( physics: AlwaysScrollableScrollPhysics(), itemBuilder: (BuildContext context, int index) { return index >= state.items.length ? BottomLoader() : ItemInfinityWidget(item: state.items[index]); }, itemCount: state.hasReachedMax ? state.items.length : state.items.length + 1, controller: _scrollController, ), onRefresh: () async { _plotDetailBloc.add(OnRefresh(widget.cropId)); }); } return Center( child: LoadingListPage(), ); }, ); } @override void dispose() { _scrollController.dispose(); super.dispose(); } } class ItemInfinityWidget extends StatelessWidget { final HistoryActivity item; const ItemInfinityWidget({Key key, @required this.item}) : super(key: key); @override Widget build(BuildContext context) { return GestureDetector( child: Card( child: ListTile( title: Text(item.activityTypeName), subtitle: Text(item.executeDate.format_DDMMYY_HHmm()), ), ), onTap: () {}); } } class ActionType { Widget addScreen; Widget listScreen; String actionName; ActionType(String actionName, Widget addScreen, Widget listScreen) { this.actionName = actionName; this.addScreen = addScreen; this.listScreen = listScreen; } }