fullscreen: swipe down to pop
This commit is contained in:
parent
6203b98ff4
commit
1976e10dee
4 changed files with 53 additions and 61 deletions
|
@ -147,14 +147,15 @@ class SectionSliver extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _showFullscreen(BuildContext context, ImageEntry entry) {
|
_showFullscreen(BuildContext context, ImageEntry entry) {
|
||||||
return Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => FullscreenPage(
|
builder: (context) => FullscreenPage(
|
||||||
collection: collection,
|
collection: collection,
|
||||||
initialUri: entry.uri,
|
initialUri: entry.uri,
|
||||||
),
|
),
|
||||||
|
fullscreenDialog: true,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,41 +28,9 @@ class FullscreenPage extends AnimatedWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return FullscreenBody(
|
||||||
backgroundColor: Colors.black,
|
collection: collection,
|
||||||
body: FullscreenBody(
|
initialUri: initialUri,
|
||||||
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,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,7 +51,7 @@ class FullscreenBody extends StatefulWidget {
|
||||||
|
|
||||||
class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProviderStateMixin {
|
class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProviderStateMixin {
|
||||||
bool _isInitialScale = true;
|
bool _isInitialScale = true;
|
||||||
int _currentHorizontalPage, _currentVerticalPage = 0;
|
int _currentHorizontalPage, _currentVerticalPage = imagePage;
|
||||||
PageController _horizontalPager, _verticalPager;
|
PageController _horizontalPager, _verticalPager;
|
||||||
ValueNotifier<bool> _overlayVisible = ValueNotifier(true);
|
ValueNotifier<bool> _overlayVisible = ValueNotifier(true);
|
||||||
AnimationController _overlayAnimationController;
|
AnimationController _overlayAnimationController;
|
||||||
|
@ -97,6 +65,10 @@ class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProvide
|
||||||
|
|
||||||
List<ImageEntry> get entries => widget.collection.sortedEntries;
|
List<ImageEntry> get entries => widget.collection.sortedEntries;
|
||||||
|
|
||||||
|
static const transitionPage = 0;
|
||||||
|
static const imagePage = 1;
|
||||||
|
static const infoPage = 2;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
@ -119,7 +91,7 @@ class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProvide
|
||||||
_overlayVisible.addListener(onOverlayVisibleChange);
|
_overlayVisible.addListener(onOverlayVisibleChange);
|
||||||
_actionDelegate = FullscreenActionDelegate(
|
_actionDelegate = FullscreenActionDelegate(
|
||||||
collection: collection,
|
collection: collection,
|
||||||
showInfo: () => goToVerticalPage(1),
|
showInfo: () => goToVerticalPage(infoPage),
|
||||||
);
|
);
|
||||||
initVideoController();
|
initVideoController();
|
||||||
initOverlay();
|
initOverlay();
|
||||||
|
@ -144,11 +116,11 @@ class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProvide
|
||||||
final entry = _currentHorizontalPage != null && _currentHorizontalPage < entries.length ? entries[_currentHorizontalPage] : null;
|
final entry = _currentHorizontalPage != null && _currentHorizontalPage < entries.length ? entries[_currentHorizontalPage] : null;
|
||||||
return WillPopScope(
|
return WillPopScope(
|
||||||
onWillPop: () {
|
onWillPop: () {
|
||||||
if (_currentVerticalPage == 1) {
|
if (_currentVerticalPage == infoPage) {
|
||||||
goToVerticalPage(0);
|
goToVerticalPage(imagePage);
|
||||||
return Future.value(false);
|
return Future.value(false);
|
||||||
}
|
}
|
||||||
SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values);
|
_onLeave();
|
||||||
return Future.value(true);
|
return Future.value(true);
|
||||||
},
|
},
|
||||||
child: Stack(
|
child: Stack(
|
||||||
|
@ -157,19 +129,23 @@ class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProvide
|
||||||
scrollDirection: Axis.vertical,
|
scrollDirection: Axis.vertical,
|
||||||
controller: _verticalPager,
|
controller: _verticalPager,
|
||||||
physics: _isInitialScale ? PageScrollPhysics() : NeverScrollableScrollPhysics(),
|
physics: _isInitialScale ? PageScrollPhysics() : NeverScrollableScrollPhysics(),
|
||||||
onPageChanged: (page) => setState(() => _currentVerticalPage = page),
|
onPageChanged: _onVerticalPageChanged,
|
||||||
children: [
|
children: [
|
||||||
ImagePage(
|
SizedBox(),
|
||||||
collection: collection,
|
Container(
|
||||||
pageController: _horizontalPager,
|
color: Colors.black,
|
||||||
onTap: () => _overlayVisible.value = !_overlayVisible.value,
|
child: ImagePage(
|
||||||
onPageChanged: onHorizontalPageChanged,
|
collection: collection,
|
||||||
onScaleChanged: (state) => setState(() => _isInitialScale = state == PhotoViewScaleState.initial),
|
pageController: _horizontalPager,
|
||||||
videoControllers: _videoControllers,
|
onTap: () => _overlayVisible.value = !_overlayVisible.value,
|
||||||
|
onPageChanged: onHorizontalPageChanged,
|
||||||
|
onScaleChanged: (state) => setState(() => _isInitialScale = state == PhotoViewScaleState.initial),
|
||||||
|
videoControllers: _videoControllers,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
NotificationListener(
|
NotificationListener(
|
||||||
onNotification: (notification) {
|
onNotification: (notification) {
|
||||||
if (notification is BackUpNotification) goToVerticalPage(0);
|
if (notification is BackUpNotification) goToVerticalPage(imagePage);
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
child: InfoPage(collection: collection, entry: entry),
|
child: InfoPage(collection: collection, entry: entry),
|
||||||
|
@ -183,7 +159,7 @@ class FullscreenBodyState extends State<FullscreenBody> with SingleTickerProvide
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> _buildOverlay(ImageEntry entry) {
|
List<Widget> _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;
|
final videoController = entry.isVideo ? _videoControllers.firstWhere((kv) => kv.item1 == entry.path, orElse: () => null)?.item2 : null;
|
||||||
return [
|
return [
|
||||||
FullscreenTopOverlay(
|
FullscreenTopOverlay(
|
||||||
|
@ -229,15 +205,29 @@ class FullscreenBodyState extends State<FullscreenBody> 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 {
|
onOverlayVisibleChange() async {
|
||||||
if (_overlayVisible.value) {
|
if (_overlayVisible.value) {
|
||||||
SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values);
|
_showSystemUI();
|
||||||
_overlayAnimationController.forward();
|
_overlayAnimationController.forward();
|
||||||
} else {
|
} else {
|
||||||
final mediaQuery = MediaQuery.of(context);
|
final mediaQuery = MediaQuery.of(context);
|
||||||
_frozenViewInsets = mediaQuery.viewInsets;
|
_frozenViewInsets = mediaQuery.viewInsets;
|
||||||
_frozenViewPadding = mediaQuery.viewPadding;
|
_frozenViewPadding = mediaQuery.viewPadding;
|
||||||
SystemChrome.setEnabledSystemUIOverlays([]);
|
_hideSystemUI();
|
||||||
await _overlayAnimationController.reverse();
|
await _overlayAnimationController.reverse();
|
||||||
_frozenViewInsets = null;
|
_frozenViewInsets = null;
|
||||||
_frozenViewPadding = null;
|
_frozenViewPadding = null;
|
||||||
|
|
|
@ -73,6 +73,7 @@ class ImagePageState extends State<ImagePage> with AutomaticKeepAliveClientMixin
|
||||||
loadingChild: Center(
|
loadingChild: Center(
|
||||||
child: CircularProgressIndicator(),
|
child: CircularProgressIndicator(),
|
||||||
),
|
),
|
||||||
|
backgroundDecoration: BoxDecoration(color: Colors.transparent),
|
||||||
pageController: widget.pageController,
|
pageController: widget.pageController,
|
||||||
onPageChanged: widget.onPageChanged,
|
onPageChanged: widget.onPageChanged,
|
||||||
scaleStateChangedCallback: widget.onScaleChanged,
|
scaleStateChangedCallback: widget.onScaleChanged,
|
||||||
|
|
14
pubspec.lock
14
pubspec.lock
|
@ -100,7 +100,7 @@ packages:
|
||||||
name: flutter_svg
|
name: flutter_svg
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.14.4"
|
version: "0.15.0"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -119,7 +119,7 @@ packages:
|
||||||
name: google_maps_flutter
|
name: google_maps_flutter
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.21+8"
|
version: "0.5.21+12"
|
||||||
image:
|
image:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -203,7 +203,7 @@ packages:
|
||||||
name: photo_view
|
name: photo_view
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.8.0"
|
version: "0.9.0"
|
||||||
printing:
|
printing:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -231,7 +231,7 @@ packages:
|
||||||
name: shared_preferences
|
name: shared_preferences
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.4+3"
|
version: "0.5.4+5"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -278,7 +278,7 @@ packages:
|
||||||
name: synchronized
|
name: synchronized
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0+1"
|
version: "2.1.0+2"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -334,7 +334,7 @@ packages:
|
||||||
name: video_player
|
name: video_player
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.10.2+5"
|
version: "0.10.3+1"
|
||||||
xml:
|
xml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -344,4 +344,4 @@ packages:
|
||||||
version: "3.5.0"
|
version: "3.5.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.5.0 <3.0.0"
|
dart: ">=2.5.0 <3.0.0"
|
||||||
flutter: ">=1.9.1 <2.0.0"
|
flutter: ">=1.9.1+hotfix.5 <2.0.0"
|
||||||
|
|
Loading…
Reference in a new issue