From 340ef3b693b861055c81247fb20378ec7ad014d9 Mon Sep 17 00:00:00 2001 From: niuhuan Date: Thu, 2 Dec 2021 10:32:35 +0800 Subject: [PATCH] fix 3 area control type can't exit reader bug, rewrite reader --- lib/basic/config/AndroidSecureFlag.dart | 2 +- lib/basic/config/FullScreenAction.dart | 10 +- lib/basic/config/NoAnimation.dart | 4 +- lib/basic/config/VolumeController.dart | 2 +- lib/screens/ComicReaderScreen.dart | 150 +++++++----------------- lib/screens/DownloadReaderScreen.dart | 134 ++++++--------------- lib/screens/components/ImageReader.dart | 145 ++++++++++++++++------- 7 files changed, 186 insertions(+), 261 deletions(-) diff --git a/lib/basic/config/AndroidSecureFlag.dart b/lib/basic/config/AndroidSecureFlag.dart index f9dfba1..7aa569a 100644 --- a/lib/basic/config/AndroidSecureFlag.dart +++ b/lib/basic/config/AndroidSecureFlag.dart @@ -37,7 +37,7 @@ Widget androidSecureFlagSetting() { return StatefulBuilder(builder: (BuildContext context, void Function(void Function()) setState) { return ListTile( - title: Text("禁止截图/禁止显示在任务视图(仅安卓)"), + title: Text("禁止截图/禁止显示在任务视图"), subtitle: Text(_androidSecureFlag ? "是" : "否"), onTap: () async { await _chooseAndroidSecureFlag(context); diff --git a/lib/basic/config/FullScreenAction.dart b/lib/basic/config/FullScreenAction.dart index c949830..30b35d9 100644 --- a/lib/basic/config/FullScreenAction.dart +++ b/lib/basic/config/FullScreenAction.dart @@ -12,9 +12,9 @@ enum FullScreenAction { } Map _fullScreenActionMap = { - "使用控制器": FullScreenAction.CONTROLLER, - "点击屏幕一次": FullScreenAction.TOUCH_ONCE, - "将屏幕划分成三个区域": FullScreenAction.THREE_AREA, + "使用控制器全屏": FullScreenAction.CONTROLLER, + "点击屏幕一次全屏": FullScreenAction.TOUCH_ONCE, + "将屏幕划分成三个区域 (上一页, 下一页, 全屏)": FullScreenAction.THREE_AREA, }; const _propertyName = "fullScreenAction"; @@ -51,7 +51,7 @@ String _currentFullScreenActionName() { Future _chooseFullScreenAction(BuildContext context) async { FullScreenAction? result = await chooseMapDialog( - context, _fullScreenActionMap, "选择进入全屏的方式"); + context, _fullScreenActionMap, "选择操控方式"); if (result != null) { await method.saveProperty(_propertyName, result.toString()); _fullScreenAction = result; @@ -62,7 +62,7 @@ Widget fullScreenActionSetting() { return StatefulBuilder( builder: (BuildContext context, void Function(void Function()) setState) { return ListTile( - title: Text("进入全屏的方式"), + title: Text("操控方式"), subtitle: Text(_currentFullScreenActionName()), onTap: () async { await _chooseFullScreenAction(context); diff --git a/lib/basic/config/NoAnimation.dart b/lib/basic/config/NoAnimation.dart index b59501c..7732212 100644 --- a/lib/basic/config/NoAnimation.dart +++ b/lib/basic/config/NoAnimation.dart @@ -19,7 +19,7 @@ bool noAnimation() { Future _chooseNoAnimation(BuildContext context) async { String? result = - await chooseListDialog(context, "取消翻页动画", ["是", "否"]); + await chooseListDialog(context, "取消键盘或音量翻页动画", ["是", "否"]); if (result != null) { var target = result == "是"; await method.saveProperty(_propertyName, "$target"); @@ -31,7 +31,7 @@ Widget noAnimationSetting() { return StatefulBuilder( builder: (BuildContext context, void Function(void Function()) setState) { return ListTile( - title: Text("取消翻页动画"), + title: Text("取消键盘或音量翻页动画"), subtitle: Text(_noAnimation ? "是" : "否"), onTap: () async { await _chooseNoAnimation(context); diff --git a/lib/basic/config/VolumeController.dart b/lib/basic/config/VolumeController.dart index bb016fb..bf0aa0b 100644 --- a/lib/basic/config/VolumeController.dart +++ b/lib/basic/config/VolumeController.dart @@ -30,7 +30,7 @@ Widget volumeControllerSetting() { return StatefulBuilder(builder: (BuildContext context, void Function(void Function()) setState) { return ListTile( - title: Text("阅读器音量键翻页(仅安卓)"), + title: Text("阅读器音量键翻页"), subtitle: Text(volumeController ? "是" : "否"), onTap: () async { await _chooseVolumeController(context); diff --git a/lib/screens/ComicReaderScreen.dart b/lib/screens/ComicReaderScreen.dart index 2233abc..8369c89 100644 --- a/lib/screens/ComicReaderScreen.dart +++ b/lib/screens/ComicReaderScreen.dart @@ -21,8 +21,6 @@ class ComicReaderScreen extends StatefulWidget { final List epList; final currentEpOrder; final int? initPicturePosition; - final ReaderType pagerType = currentReaderType(); - final ReaderDirection pagerDirection = gReaderDirection; late final bool autoFullScreen; ComicReaderScreen({ @@ -78,54 +76,42 @@ class _ComicReaderScreenState extends State { widget.comicInfo.id, _ep.order, _ep.title, position); } - FutureOr Function() _previousAction = () => null; - - String _nextText = ""; - FutureOr Function() _nextAction = () => null; - - @override - void initState() { - // NEXT + FutureOr _onChangeEp(int epOrder) { var orderMap = Map(); widget.epList.forEach((element) { orderMap[element.order] = element; }); - if (orderMap.containsKey(widget.currentEpOrder - 1)) { - _previousAction = () { - _replacement = true; - Navigator.of(context).pushReplacement( - MaterialPageRoute( - builder: (context) => ComicReaderScreen( - comicInfo: widget.comicInfo, - epList: widget.epList, - currentEpOrder: widget.currentEpOrder - 1, - autoFullScreen: _fullScreen, - ), + if (orderMap.containsKey(epOrder)) { + _replacement = true; + Navigator.of(context).pushReplacement( + MaterialPageRoute( + builder: (context) => ComicReaderScreen( + comicInfo: widget.comicInfo, + epList: widget.epList, + currentEpOrder: epOrder, + autoFullScreen: _fullScreen, ), - ); - }; - } else { - _previousAction = () => defaultToast(context, "已经到头了"); - } - if (orderMap.containsKey(widget.currentEpOrder + 1)) { - _nextText = "下一章"; - _nextAction = () { - _replacement = true; - Navigator.of(context).pushReplacement( - MaterialPageRoute( - builder: (context) => ComicReaderScreen( - comicInfo: widget.comicInfo, - epList: widget.epList, - currentEpOrder: widget.currentEpOrder + 1, - autoFullScreen: _fullScreen, - ), - ), - ); - }; - } else { - _nextText = "阅读结束"; - _nextAction = () => Navigator.of(context).pop(); + ), + ); } + } + + FutureOr _onReloadEp() { + _replacement = true; + Navigator.of(context).pushReplacement(MaterialPageRoute( + builder: (context) => ComicReaderScreen( + comicInfo: widget.comicInfo, + epList: widget.epList, + currentEpOrder: widget.currentEpOrder, + initPicturePosition: _lastChangeRank ?? widget.initPicturePosition, + // maybe null + autoFullScreen: _fullScreen, + ), + )); + } + + @override + void initState() { // EP widget.epList.forEach((element) { if (element.order == widget.currentEpOrder) { @@ -150,20 +136,6 @@ class _ComicReaderScreenState extends State { return readerKeyboardHolder(_build(context)); } - Future _onSelectDirection() async { - await choosePagerDirection(context); - if (widget.pagerDirection != gReaderDirection) { - _reloadReader(); - } - } - - Future _onSelectReaderType() async { - await choosePagerType(context); - if (widget.pagerType != currentReaderType()) { - _reloadReader(); - } - } - Widget _build(BuildContext context) { return FutureBuilder( future: _future, @@ -176,16 +148,6 @@ class _ComicReaderScreenState extends State { : AppBar( backgroundColor: readerAppbarColor, title: Text("${_ep.title} - ${widget.comicInfo.title}"), - actions: [ - IconButton( - onPressed: _onSelectDirection, - icon: Icon(Icons.grid_goldenratio), - ), - IconButton( - onPressed: _onSelectReaderType, - icon: Icon(Icons.view_day_outlined), - ), - ], ), body: ContentError( error: snapshot.error, @@ -205,16 +167,6 @@ class _ComicReaderScreenState extends State { : AppBar( backgroundColor: readerAppbarColor, title: Text("${_ep.title} - ${widget.comicInfo.title}"), - actions: [ - IconButton( - onPressed: _onSelectDirection, - icon: Icon(Icons.grid_goldenratio), - ), - IconButton( - onPressed: _onSelectReaderType, - icon: Icon(Icons.view_day_outlined), - ), - ], ), body: ContentLoading(label: '加载中'), ); @@ -224,33 +176,28 @@ class _ComicReaderScreenState extends State { epNameMap[element.order] = element.title; }); return Scaffold( - body: ImageReader( + body: ImageReader( ImageReaderStruct( images: snapshot.data! .map((e) => ReaderImageInfo( - e.fileServer, - e.path, - null, - null, - null, - null, - null, - )) + e.fileServer, + e.path, + null, + null, + null, + null, + null, + )) .toList(), fullScreen: _fullScreen, onFullScreenChange: _onFullScreenChange, - onNextText: _nextText, - onPreviousAction: _previousAction, - onNextAction: _nextAction, onPositionChange: _onPositionChange, initPosition: widget.initPicturePosition, - pagerType: widget.pagerType, - pagerDirection: widget.pagerDirection, epNameMap: epNameMap, epOrder: _ep.order, comicTitle: widget.comicInfo.title, - onSelectDirection: _onSelectDirection, - onSelectReaderType: _onSelectReaderType, + onChangeEp: _onChangeEp, + onReloadEp: _onReloadEp, ), ), ); @@ -265,19 +212,4 @@ class _ComicReaderScreenState extends State { _fullScreen = fullScreen; }); } - - // 重新加载本页 - void _reloadReader() { - _replacement = true; - Navigator.of(context).pushReplacement(MaterialPageRoute( - builder: (context) => ComicReaderScreen( - comicInfo: widget.comicInfo, - epList: widget.epList, - currentEpOrder: widget.currentEpOrder, - initPicturePosition: _lastChangeRank ?? widget.initPicturePosition, - // maybe null - autoFullScreen: _fullScreen, - ), - )); - } } diff --git a/lib/screens/DownloadReaderScreen.dart b/lib/screens/DownloadReaderScreen.dart index 7362b3c..78dedeb 100644 --- a/lib/screens/DownloadReaderScreen.dart +++ b/lib/screens/DownloadReaderScreen.dart @@ -71,54 +71,44 @@ class _DownloadReaderScreenState extends State { widget.comicInfo.id, _ep.epOrder, _ep.title, position); } - FutureOr Function() _previousAction = () => null; - - String _nextText = ""; - FutureOr Function() _nextAction = () => null; - - @override - void initState() { - // NEXT + FutureOr _onChangeEp(int epOrder) { var orderMap = Map(); widget.epList.forEach((element) { orderMap[element.epOrder] = element; }); - if (orderMap.containsKey(widget.currentEpOrder - 1)) { - _previousAction = () { - _replacement = true; - Navigator.of(context).pushReplacement( - MaterialPageRoute( - builder: (context) => DownloadReaderScreen( - comicInfo: widget.comicInfo, - epList: widget.epList, - currentEpOrder: widget.currentEpOrder - 1, - autoFullScreen: _fullScreen, - ), + if (orderMap.containsKey(epOrder)) { + _replacement = true; + Navigator.of(context).pushReplacement( + MaterialPageRoute( + builder: (context) => DownloadReaderScreen( + comicInfo: widget.comicInfo, + epList: widget.epList, + currentEpOrder: epOrder, + autoFullScreen: _fullScreen, ), - ); - }; - } else { - _previousAction = () => defaultToast(context, "已经到头了"); - } - if (orderMap.containsKey(widget.currentEpOrder + 1)) { - _nextText = "下一章"; - _nextAction = () { - _replacement = true; - Navigator.of(context).pushReplacement( - MaterialPageRoute( - builder: (context) => DownloadReaderScreen( - comicInfo: widget.comicInfo, - epList: widget.epList, - currentEpOrder: widget.currentEpOrder + 1, - autoFullScreen: _fullScreen, - ), - ), - ); - }; - } else { - _nextText = "阅读结束"; - _nextAction = () => Navigator.of(context).pop(); + ), + ); } + } + + FutureOr _onReloadEp() { + _replacement = true; + Navigator.of(context).pushReplacement( + MaterialPageRoute( + builder: (context) => DownloadReaderScreen( + comicInfo: widget.comicInfo, + epList: widget.epList, + currentEpOrder: widget.currentEpOrder, + initPicturePosition: _lastChangeRank ?? widget.initPicturePosition, + // maybe null + autoFullScreen: _fullScreen, + ), + ), + ); + } + + @override + void initState() { // EP widget.epList.forEach((element) { if (element.epOrder == widget.currentEpOrder) { @@ -143,20 +133,6 @@ class _DownloadReaderScreenState extends State { return readerKeyboardHolder(_build(context)); } - Future _onSelectDirection() async { - await choosePagerDirection(context); - if (widget.pagerDirection != gReaderDirection) { - _reloadReader(); - } - } - - Future _onSelectReaderType() async { - await choosePagerType(context); - if (widget.pagerType != currentReaderType()) { - _reloadReader(); - } - } - Widget _build(BuildContext context) { return FutureBuilder( future: _future, @@ -167,16 +143,6 @@ class _DownloadReaderScreenState extends State { ? null : AppBar( title: Text("${_ep.title} - ${widget.comicInfo.title}"), - actions: [ - IconButton( - onPressed: _onSelectDirection, - icon: Icon(Icons.grid_goldenratio), - ), - IconButton( - onPressed: _onSelectReaderType, - icon: Icon(Icons.view_day_outlined), - ), - ], ), body: ContentError( error: snapshot.error, @@ -195,16 +161,6 @@ class _DownloadReaderScreenState extends State { ? null : AppBar( title: Text("${_ep.title} - ${widget.comicInfo.title}"), - actions: [ - IconButton( - onPressed: _onSelectDirection, - icon: Icon(Icons.grid_goldenratio), - ), - IconButton( - onPressed: _onSelectReaderType, - icon: Icon(Icons.view_day_outlined), - ), - ], ), body: ContentLoading(label: '加载中'), ); @@ -222,18 +178,13 @@ class _DownloadReaderScreenState extends State { .toList(), fullScreen: _fullScreen, onFullScreenChange: _onFullScreenChange, - onNextText: _nextText, - onPreviousAction: _previousAction, - onNextAction: _nextAction, onPositionChange: _onPositionChange, initPosition: widget.initPicturePosition, - pagerType: widget.pagerType, - pagerDirection: widget.pagerDirection, epOrder: _ep.epOrder, epNameMap: epNameMap, comicTitle: widget.comicInfo.title, - onSelectDirection: _onSelectDirection, - onSelectReaderType: _onSelectReaderType, + onReloadEp: _onReloadEp, + onChangeEp: _onChangeEp, ), ), ); @@ -248,21 +199,4 @@ class _DownloadReaderScreenState extends State { _fullScreen = fullScreen; }); } - - // 重新加载本页 - void _reloadReader() { - _replacement = true; - Navigator.of(context).pushReplacement( - MaterialPageRoute( - builder: (context) => DownloadReaderScreen( - comicInfo: widget.comicInfo, - epList: widget.epList, - currentEpOrder: widget.currentEpOrder, - initPicturePosition: _lastChangeRank ?? widget.initPicturePosition, - // maybe null - autoFullScreen: _fullScreen, - ), - ), - ); - } } diff --git a/lib/screens/components/ImageReader.dart b/lib/screens/components/ImageReader.dart index 51ffc09..c5bd651 100644 --- a/lib/screens/components/ImageReader.dart +++ b/lib/screens/components/ImageReader.dart @@ -107,35 +107,25 @@ class ImageReaderStruct { final List images; final bool fullScreen; final FutureOr Function(bool fullScreen) onFullScreenChange; - final String onNextText; - final FutureOr Function() onPreviousAction; - final FutureOr Function() onNextAction; final FutureOr Function(int) onPositionChange; final int? initPosition; - final ReaderType pagerType; - final ReaderDirection pagerDirection; final Map epNameMap; final int epOrder; final String comicTitle; - final FutureOr Function() onSelectDirection; - final FutureOr Function() onSelectReaderType; + final FutureOr Function(int) onChangeEp; + final FutureOr Function() onReloadEp; const ImageReaderStruct({ required this.images, required this.fullScreen, required this.onFullScreenChange, - required this.onNextText, - required this.onPreviousAction, - required this.onNextAction, required this.onPositionChange, this.initPosition, - required this.pagerType, - required this.pagerDirection, required this.epNameMap, required this.epOrder, required this.comicTitle, - required this.onSelectDirection, - required this.onSelectReaderType, + required this.onChangeEp, + required this.onReloadEp, }); } @@ -146,9 +136,39 @@ class ImageReader extends StatefulWidget { const ImageReader(this.struct); + @override + State createState() => _ImageReaderState(); +} + +class _ImageReaderState extends State { + // 记录初始方向 + final ReaderDirection pagerDirection = gReaderDirection; + + // 记录初始阅读器类型 + final ReaderType pagerType = currentReaderType(); + + @override + Widget build(BuildContext context) { + return _ImageReaderContent(widget.struct, pagerDirection, pagerType); + } +} + +// + +class _ImageReaderContent extends StatefulWidget { + // 记录初始方向 + final ReaderDirection pagerDirection; + + // 记录初始阅读器类型 + final ReaderType pagerType; + + final ImageReaderStruct struct; + + const _ImageReaderContent(this.struct, this.pagerDirection, this.pagerType); + @override State createState() { - switch (struct.pagerType) { + switch (pagerType) { case ReaderType.WEB_TOON: return _WebToonReaderState(); case ReaderType.WEB_TOON_ZOOM: @@ -161,13 +181,14 @@ class ImageReader extends StatefulWidget { } } -abstract class _ImageReaderState extends State { +abstract class _ImageReaderContentState extends State<_ImageReaderContent> { // 阅读器 Widget _buildViewer(); // 键盘, 音量键 等事件 void _needJumpTo(int index, bool animation); + // 记录了是否切换了音量 late bool _listVolume; @override @@ -275,11 +296,11 @@ abstract class _ImageReaderState extends State { backgroundColor: readerAppbarColor2, actions: [ IconButton( - onPressed: widget.struct.onSelectDirection, + onPressed: _onSelectDirection, icon: Icon(Icons.grid_goldenratio), ), IconButton( - onPressed: widget.struct.onSelectReaderType, + onPressed: _onSelectReaderType, icon: Icon(Icons.view_day_outlined), ), ], @@ -364,9 +385,7 @@ abstract class _ImageReaderState extends State { IconButton( icon: Icon(Icons.skip_next_outlined), color: Colors.white, - onPressed: () { - widget.struct.onNextAction(); - }, + onPressed: _onNextAction, ), Container(width: 15), ], @@ -453,7 +472,7 @@ abstract class _ImageReaderState extends State { ), ); late Widget child; - switch (widget.struct.pagerDirection) { + switch (widget.pagerDirection) { case ReaderDirection.TOP_TO_BOTTOM: child = Column(children: [ up, @@ -479,16 +498,53 @@ abstract class _ImageReaderState extends State { return Container( width: constraints.maxWidth, height: constraints.maxHeight, - child: child, + child: Column( + children: [ + Container( + height: widget.struct.fullScreen + ? 0 + : Scaffold.of(context).appBarMaxHeight ?? 0, + ), + Expanded(child: child), + Container( + height: widget.struct.fullScreen ? 0 : 45, + ), + ], + ), ); }, ); } + + Future _onSelectDirection() async { + await choosePagerDirection(context); + if (widget.pagerDirection != gReaderDirection) { + widget.struct.onReloadEp(); + } + } + + Future _onSelectReaderType() async { + await choosePagerType(context); + if (widget.pagerType != currentReaderType()) { + widget.struct.onReloadEp(); + } + } + + Future _onNextAction() async { + if (widget.struct.epNameMap.containsKey(widget.struct.epOrder + 1)) { + widget.struct.onChangeEp(widget.struct.epOrder + 1); + } else { + defaultToast(context, "已经到头了"); + } + } + + bool _hasNextEp() => + widget.struct.epNameMap.containsKey(widget.struct.epOrder + 1); } /////////////////////////////////////////////////////////////////////////////// -class _WebToonReaderState extends _ImageReaderState { +class _WebToonReaderState extends _ImageReaderContentState { var _controllerTime = DateTime.now().millisecondsSinceEpoch + 400; late final List _trueSizes = []; late final ItemScrollController _itemScrollController; @@ -560,7 +616,7 @@ class _WebToonReaderState extends _ImageReaderState { for (var index = 0; index < widget.struct.images.length; index++) { late Size renderSize; if (_trueSizes[index] != null) { - if (widget.struct.pagerDirection == ReaderDirection.TOP_TO_BOTTOM) { + if (widget.pagerDirection == ReaderDirection.TOP_TO_BOTTOM) { renderSize = Size( constraints.maxWidth, constraints.maxWidth * @@ -576,7 +632,7 @@ class _WebToonReaderState extends _ImageReaderState { ); } } else { - if (widget.struct.pagerDirection == ReaderDirection.TOP_TO_BOTTOM) { + if (widget.pagerDirection == ReaderDirection.TOP_TO_BOTTOM) { renderSize = Size(constraints.maxWidth, constraints.maxWidth / 2); } else { // ReaderDirection.LEFT_TO_RIGHT @@ -616,19 +672,17 @@ class _WebToonReaderState extends _ImageReaderState { return ScrollablePositionedList.builder( initialScrollIndex: super._startIndex, scrollDirection: - widget.struct.pagerDirection == ReaderDirection.TOP_TO_BOTTOM + widget.pagerDirection == ReaderDirection.TOP_TO_BOTTOM ? Axis.vertical : Axis.horizontal, - reverse: - widget.struct.pagerDirection == ReaderDirection.RIGHT_TO_LEFT, + reverse: widget.pagerDirection == ReaderDirection.RIGHT_TO_LEFT, padding: EdgeInsets.only( top: (scaffold.appBarMaxHeight ?? 0), - bottom: - widget.struct.pagerDirection == ReaderDirection.TOP_TO_BOTTOM - ? 130 - : (widget.struct.fullScreen - ? (scaffold.appBarMaxHeight ?? 0) - : 45), + bottom: widget.pagerDirection == ReaderDirection.TOP_TO_BOTTOM + ? 130 + : (widget.struct.fullScreen + ? (scaffold.appBarMaxHeight ?? 0) + : 45), ), itemScrollController: _itemScrollController, itemPositionsListener: _itemPositionsListener, @@ -648,11 +702,17 @@ class _WebToonReaderState extends _ImageReaderState { return Container( padding: EdgeInsets.all(20), child: MaterialButton( - onPressed: widget.struct.onNextAction, + onPressed: () { + if (super._hasNextEp()) { + super._onNextAction(); + } else { + Navigator.of(context).pop(); + } + }, textColor: Colors.white, child: Container( padding: EdgeInsets.only(top: 40, bottom: 40), - child: Text(widget.struct.onNextText), + child: Text(super._hasNextEp() ? '下一章' : '结束阅读'), ), ), ); @@ -794,7 +854,7 @@ class _WebToonZoomReaderState extends _WebToonReaderState { /////////////////////////////////////////////////////////////////////////////// -class _GalleryReaderState extends _ImageReaderState { +class _GalleryReaderState extends _ImageReaderContentState { late PageController _pageController; @override @@ -834,11 +894,10 @@ class _GalleryReaderState extends _ImageReaderState { Widget _buildViewer() { Widget gallery = PhotoViewGallery.builder( - scrollDirection: - widget.struct.pagerDirection == ReaderDirection.TOP_TO_BOTTOM - ? Axis.vertical - : Axis.horizontal, - reverse: widget.struct.pagerDirection == ReaderDirection.RIGHT_TO_LEFT, + scrollDirection: widget.pagerDirection == ReaderDirection.TOP_TO_BOTTOM + ? Axis.vertical + : Axis.horizontal, + reverse: widget.pagerDirection == ReaderDirection.RIGHT_TO_LEFT, backgroundDecoration: BoxDecoration(color: Colors.black), loadingBuilder: (context, event) => LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) {