import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_platform_widgets/flutter_platform_widgets.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:imagini/blocs/home_bloc.dart'; import 'package:imagini/core/app_provider.dart'; class HomeScreen extends StatefulWidget { static const String PATH = '/Home'; HomeScreen({Key key}) : super(key: key); @override _HomeScreenState createState() => _HomeScreenState(); } class _HomeScreenState extends State { HomeBloc bloc; ScrollController _gridViewController = new ScrollController(); ScrollController _parentController = new ScrollController(); int _currentIndex = 0; int _totalLength = 1; double _lastOffset = 0.0; @override Widget build(BuildContext context) { _init(); return PlatformScaffold( body: _buildBody(), bottomNavBar: _buildNavBar() ); } void _init(){ _gridViewController.addListener(_scrollListener); if(bloc != null) return; bloc = HomeBloc(AppProvider.getApplication(context)); } // Needed Due to Nested Scroll Views void _scrollListener() { // Reflect Downwards & Upwards Scrolling (Respectively) on Parent if (_gridViewController.offset > _lastOffset) { if (_parentController.offset < _parentController.position.maxScrollExtent) { _parentController.jumpTo(_parentController.offset + (_lastOffset - _gridViewController.offset).abs()); } } else if (_gridViewController.offset < _lastOffset) { if (_parentController.offset > 0) { _parentController.jumpTo(_parentController.offset - (_lastOffset - _gridViewController.offset).abs()); } } // Don't update offset on top or bottom bounce if (_gridViewController.offset < _gridViewController.position.maxScrollExtent && _gridViewController.offset > 0) _lastOffset = _gridViewController.offset; } @override void dispose() { super.dispose(); // bloc.dispose(); } Widget _buildBody() { var widgetMap = [ [ _buildAppBar("Gallery"), SliverFillRemaining( child: _buildGridView() ) ], [ _buildAppBar("Albums"), SliverToBoxAdapter() ], [ _buildAppBar("Settings"), SliverToBoxAdapter() ], ]; return CustomScrollView( shrinkWrap: true, controller: _parentController, slivers: widgetMap[_currentIndex], ); } Widget _buildAppBar(String title) { return SliverAppBar( title: new Text(title), pinned: false, snap: false, floating: true, leading: PlatformIconButton( icon: Icon(PlatformIcons(context).person), ), actions: [ PlatformIconButton( icon: Icon(PlatformIcons(context).search), ), PlatformIconButton( icon: Icon(PlatformIcons(context).add), ), ], ); } Widget _buildNavBar() { return PlatformNavBar( currentIndex: _currentIndex, itemChanged: (index) => setState(() { _currentIndex = index; }), items: [ BottomNavigationBarItem( label: "Photos", icon: Icon(isMaterial(context) ? Icons.insert_photo : CupertinoIcons.photo), ), BottomNavigationBarItem( label: "Albums", icon: Icon(isMaterial(context) ? Icons.collections : CupertinoIcons.photo_on_rectangle), ), BottomNavigationBarItem( label: "Settings", icon: Icon(PlatformIcons(context).settings), ), ], ); } Widget _appLoading(){ return Center( child: ConstrainedBox( constraints: BoxConstraints(maxWidth: 500), child: Container( margin: EdgeInsets.fromLTRB(50, 0, 50, 0), height: 370, child: Column( children: [ PlatformCircularProgressIndicator() ], ), ), ), ); } Widget _buildGridView() { MediaQueryData queryData = MediaQuery.of(context); final int itemMultiplier = 3; final int crossAxisCount = (queryData.size.width * itemMultiplier / 500).ceil(); final int derivedContentWidth = 500; return new StaggeredGridView.builder( shrinkWrap: true, itemCount: _totalLength, controller: _gridViewController, gridDelegate: SliverStaggeredGridDelegateWithFixedCrossAxisCount( staggeredTileCount: _totalLength, crossAxisCount: crossAxisCount, mainAxisSpacing: 4.0, crossAxisSpacing: 4.0, staggeredTileBuilder: (int index) => new StaggeredTile.fit(1), ), itemBuilder: (BuildContext context, int index) { return _buildCard(index, derivedContentWidth); }, ); } Widget _buildCard(index, derivedContentWidth) { return FutureBuilder( future: bloc.getMedia(index, derivedContentWidth), builder: (context, snapshot) { if (!snapshot.hasData) return SizedBox(width: 500, height: 500); WidgetsBinding.instance.addPostFrameCallback((_) { if (_totalLength == bloc.totalMediaItems) return; setState(() { _totalLength = bloc.totalMediaItems; }); }); return snapshot.data; // WidgetsBinding.instance.addPostFrameCallback((_) { // if (_totalLength == bloc.cachedMediaItemList.length - 1) // return; // if (bloc.cachedMediaItemList.length == 0) // return; // setState(() { // _totalLength = bloc.cachedMediaItemList.length - 1; // }); // }); } ); } }