From 1976e10deed7718ceba173c16eaa222b32f2bc5c Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sun, 24 Nov 2019 18:29:16 +0900 Subject: [PATCH] fullscreen: swipe down to pop --- lib/widgets/album/thumbnail_collection.dart | 5 +- lib/widgets/fullscreen/fullscreen_page.dart | 94 +++++++++------------ lib/widgets/fullscreen/image_page.dart | 1 + pubspec.lock | 14 +-- 4 files changed, 53 insertions(+), 61 deletions(-) diff --git a/lib/widgets/album/thumbnail_collection.dart b/lib/widgets/album/thumbnail_collection.dart index 2bb9fe31e..661118536 100644 --- a/lib/widgets/album/thumbnail_collection.dart +++ b/lib/widgets/album/thumbnail_collection.dart @@ -147,14 +147,15 @@ class SectionSliver extends StatelessWidget { ); } - Future _showFullscreen(BuildContext context, ImageEntry entry) { - return Navigator.push( + _showFullscreen(BuildContext context, ImageEntry entry) { + Navigator.push( context, MaterialPageRoute( builder: (context) => FullscreenPage( collection: collection, initialUri: entry.uri, ), + fullscreenDialog: true, ), ); } diff --git a/lib/widgets/fullscreen/fullscreen_page.dart b/lib/widgets/fullscreen/fullscreen_page.dart index dfe60b5d0..9fc4bf72f 100644 --- a/lib/widgets/fullscreen/fullscreen_page.dart +++ b/lib/widgets/fullscreen/fullscreen_page.dart @@ -28,41 +28,9 @@ class FullscreenPage extends AnimatedWidget { @override Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Colors.black, - body: FullscreenBody( - collection: collection, - initialUri: initialUri, - ), - resizeToAvoidBottomInset: false, -// Hero( -// tag: uri, -// child: Stack( -// children: [ -// Center( -// child: widget.thumbnail == null -// ? CircularProgressIndicator() -// : Image.memory( -// widget.thumbnail, -// width: requestWidth, -// height: requestHeight, -// fit: BoxFit.contain, -// ), -// ), -// Center( -// child: FadeInImage( -// placeholder: MemoryImage(kTransparentImage), -// image: FileImage(File(path)), -// fadeOutDuration: Duration(milliseconds: 1), -// fadeInDuration: Duration(milliseconds: 200), -// width: requestWidth, -// height: requestHeight, -// fit: BoxFit.contain, -// ), -// ), -// ], -// ), -// ), + return FullscreenBody( + collection: collection, + initialUri: initialUri, ); } } @@ -83,7 +51,7 @@ class FullscreenBody extends StatefulWidget { class FullscreenBodyState extends State with SingleTickerProviderStateMixin { bool _isInitialScale = true; - int _currentHorizontalPage, _currentVerticalPage = 0; + int _currentHorizontalPage, _currentVerticalPage = imagePage; PageController _horizontalPager, _verticalPager; ValueNotifier _overlayVisible = ValueNotifier(true); AnimationController _overlayAnimationController; @@ -97,6 +65,10 @@ class FullscreenBodyState extends State with SingleTickerProvide List get entries => widget.collection.sortedEntries; + static const transitionPage = 0; + static const imagePage = 1; + static const infoPage = 2; + @override void initState() { super.initState(); @@ -119,7 +91,7 @@ class FullscreenBodyState extends State with SingleTickerProvide _overlayVisible.addListener(onOverlayVisibleChange); _actionDelegate = FullscreenActionDelegate( collection: collection, - showInfo: () => goToVerticalPage(1), + showInfo: () => goToVerticalPage(infoPage), ); initVideoController(); initOverlay(); @@ -144,11 +116,11 @@ class FullscreenBodyState extends State with SingleTickerProvide final entry = _currentHorizontalPage != null && _currentHorizontalPage < entries.length ? entries[_currentHorizontalPage] : null; return WillPopScope( onWillPop: () { - if (_currentVerticalPage == 1) { - goToVerticalPage(0); + if (_currentVerticalPage == infoPage) { + goToVerticalPage(imagePage); return Future.value(false); } - SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values); + _onLeave(); return Future.value(true); }, child: Stack( @@ -157,19 +129,23 @@ class FullscreenBodyState extends State with SingleTickerProvide scrollDirection: Axis.vertical, controller: _verticalPager, physics: _isInitialScale ? PageScrollPhysics() : NeverScrollableScrollPhysics(), - onPageChanged: (page) => setState(() => _currentVerticalPage = page), + onPageChanged: _onVerticalPageChanged, children: [ - ImagePage( - collection: collection, - pageController: _horizontalPager, - onTap: () => _overlayVisible.value = !_overlayVisible.value, - onPageChanged: onHorizontalPageChanged, - onScaleChanged: (state) => setState(() => _isInitialScale = state == PhotoViewScaleState.initial), - videoControllers: _videoControllers, + SizedBox(), + Container( + color: Colors.black, + child: ImagePage( + collection: collection, + pageController: _horizontalPager, + onTap: () => _overlayVisible.value = !_overlayVisible.value, + onPageChanged: onHorizontalPageChanged, + onScaleChanged: (state) => setState(() => _isInitialScale = state == PhotoViewScaleState.initial), + videoControllers: _videoControllers, + ), ), NotificationListener( onNotification: (notification) { - if (notification is BackUpNotification) goToVerticalPage(0); + if (notification is BackUpNotification) goToVerticalPage(imagePage); return false; }, child: InfoPage(collection: collection, entry: entry), @@ -183,7 +159,7 @@ class FullscreenBodyState extends State with SingleTickerProvide } List _buildOverlay(ImageEntry entry) { - if (entry == null || _currentVerticalPage != 0) return []; + if (entry == null || _currentVerticalPage != imagePage) return []; final videoController = entry.isVideo ? _videoControllers.firstWhere((kv) => kv.item1 == entry.path, orElse: () => null)?.item2 : null; return [ FullscreenTopOverlay( @@ -229,15 +205,29 @@ class FullscreenBodyState extends State with SingleTickerProvide ); } + _onVerticalPageChanged(page) { + setState(() => _currentVerticalPage = page); + if (_currentVerticalPage == transitionPage) { + _onLeave(); + Navigator.pop(context); + } + } + + _onLeave() => _showSystemUI(); + + _showSystemUI() => SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values); + + _hideSystemUI() => SystemChrome.setEnabledSystemUIOverlays([]); + onOverlayVisibleChange() async { if (_overlayVisible.value) { - SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values); + _showSystemUI(); _overlayAnimationController.forward(); } else { final mediaQuery = MediaQuery.of(context); _frozenViewInsets = mediaQuery.viewInsets; _frozenViewPadding = mediaQuery.viewPadding; - SystemChrome.setEnabledSystemUIOverlays([]); + _hideSystemUI(); await _overlayAnimationController.reverse(); _frozenViewInsets = null; _frozenViewPadding = null; diff --git a/lib/widgets/fullscreen/image_page.dart b/lib/widgets/fullscreen/image_page.dart index e20b6e12d..11d21297f 100644 --- a/lib/widgets/fullscreen/image_page.dart +++ b/lib/widgets/fullscreen/image_page.dart @@ -73,6 +73,7 @@ class ImagePageState extends State with AutomaticKeepAliveClientMixin loadingChild: Center( child: CircularProgressIndicator(), ), + backgroundDecoration: BoxDecoration(color: Colors.transparent), pageController: widget.pageController, onPageChanged: widget.onPageChanged, scaleStateChangedCallback: widget.onScaleChanged, diff --git a/pubspec.lock b/pubspec.lock index fddf88f60..ab6277eb7 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -100,7 +100,7 @@ packages: name: flutter_svg url: "https://pub.dartlang.org" source: hosted - version: "0.14.4" + version: "0.15.0" flutter_test: dependency: "direct dev" description: flutter @@ -119,7 +119,7 @@ packages: name: google_maps_flutter url: "https://pub.dartlang.org" source: hosted - version: "0.5.21+8" + version: "0.5.21+12" image: dependency: transitive description: @@ -203,7 +203,7 @@ packages: name: photo_view url: "https://pub.dartlang.org" source: hosted - version: "0.8.0" + version: "0.9.0" printing: dependency: "direct main" description: @@ -231,7 +231,7 @@ packages: name: shared_preferences url: "https://pub.dartlang.org" source: hosted - version: "0.5.4+3" + version: "0.5.4+5" sky_engine: dependency: transitive description: flutter @@ -278,7 +278,7 @@ packages: name: synchronized url: "https://pub.dartlang.org" source: hosted - version: "2.1.0+1" + version: "2.1.0+2" term_glyph: dependency: transitive description: @@ -334,7 +334,7 @@ packages: name: video_player url: "https://pub.dartlang.org" source: hosted - version: "0.10.2+5" + version: "0.10.3+1" xml: dependency: transitive description: @@ -344,4 +344,4 @@ packages: version: "3.5.0" sdks: dart: ">=2.5.0 <3.0.0" - flutter: ">=1.9.1 <2.0.0" + flutter: ">=1.9.1+hotfix.5 <2.0.0"