Skip to content

Commit

Permalink
Fix the bug that auto reading mode cannot scroll to the end in some s…
Browse files Browse the repository at this point in the history
…cenes

修复在部分场景下,自动阅读模式无法滚动到末尾的bug
  • Loading branch information
jiangtian616 committed Nov 27, 2023
1 parent 8abd6a8 commit f9f5983
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 19 deletions.
5 changes: 5 additions & 0 deletions changelog/v7.4.8+147.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
- 修复在部分场景下,自动阅读模式无法滚动到末尾的bug

------------------------------------------------------------------------------------------

- Fix the bug that auto reading mode cannot scroll to the end in some scenes
Original file line number Diff line number Diff line change
Expand Up @@ -153,14 +153,12 @@ class HorizontalListLayoutLogic extends BaseLayoutLogic {

void _enterAutoModeByScroll() {
int restPageCount = readPageState.readPageInfo.pageCount - readPageState.readPageInfo.currentImageIndex - 1;
double offset = restPageCount * screenHeight;
double totalTime = restPageCount * ReadSetting.autoModeInterval.value;

readPageLogic.toggleMenu();

state.itemScrollController
.scrollOffset(
offset: offset,
.scrollToEnd(
duration: Duration(milliseconds: (totalTime * 1000).toInt()),
)
.then((_) => readPageLogic.closeAutoMode());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,12 @@ class VerticalListLayoutLogic extends BaseLayoutLogic {

void _enterAutoModeByScroll() {
int restPageCount = readPageState.readPageInfo.pageCount - readPageState.readPageInfo.currentImageIndex - 1;
double offset = restPageCount * screenHeight;
double totalTime = restPageCount * ReadSetting.autoModeInterval.value;

readPageLogic.toggleMenu();

state.itemScrollController
.scrollOffset(
offset: offset,
.scrollToEnd(
duration: Duration(milliseconds: (totalTime * 1000).toInt()),
)
.then((_) => readPageLogic.closeAutoMode());
Expand Down
64 changes: 51 additions & 13 deletions lib/src/pages/read/widget/eh_scrollable_positioned_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,21 @@ class EHItemScrollController {
);
}

Future<void> scrollToEnd({
required Duration duration,
Curve curve = Curves.linear,
List<double> opacityAnimationWeights = const [40, 20, 40],
}) {
assert(_scrollableListState != null);
assert(opacityAnimationWeights.length == 3);
assert(duration > Duration.zero);
return _scrollableListState!._scrollToEnd(
duration: duration,
curve: curve,
opacityAnimationWeights: opacityAnimationWeights,
);
}

void _attach(_EHScrollablePositionedListState scrollableListState) {
assert(_scrollableListState == null);
_scrollableListState = scrollableListState;
Expand Down Expand Up @@ -480,6 +495,33 @@ class _EHScrollablePositionedListState extends State<EHScrollablePositionedList>
}
}

Future<void> _scrollToEnd({
required Duration duration,
Curve curve = Curves.linear,
required List<double> opacityAnimationWeights,
}) async {
if (_isTransitioning) {
_stopScroll(canceled: true);
SchedulerBinding.instance.addPostFrameCallback((_) {
_startScrollOffset(
offset: primary.scrollController.position.maxScrollExtent - primary.scrollController.position.pixels,
alignment: 0,
duration: duration,
curve: curve,
opacityAnimationWeights: opacityAnimationWeights,
);
});
} else {
await _startScrollOffset(
offset: primary.scrollController.position.maxScrollExtent - primary.scrollController.position.pixels,
alignment: 0,
duration: duration,
curve: curve,
opacityAnimationWeights: opacityAnimationWeights,
);
}
}

Future<void> _startScroll({
required int index,
required double alignment,
Expand All @@ -488,15 +530,13 @@ class _EHScrollablePositionedListState extends State<EHScrollablePositionedList>
required List<double> opacityAnimationWeights,
}) async {
final direction = index > primary.target ? 1 : -1;
final itemPosition = primary.itemPositionsNotifier.itemPositions.value
.firstWhereOrNull((ItemPosition itemPosition) => itemPosition.index == index);
final itemPosition =
primary.itemPositionsNotifier.itemPositions.value.firstWhereOrNull((ItemPosition itemPosition) => itemPosition.index == index);
if (itemPosition != null) {
// Scroll directly.
final localScrollAmount = itemPosition.itemLeadingEdge * primary.scrollController.position.viewportDimension;
await primary.scrollController.animateTo(
primary.scrollController.offset +
localScrollAmount -
alignment * primary.scrollController.position.viewportDimension,
primary.scrollController.offset + localScrollAmount - alignment * primary.scrollController.position.viewportDimension,
duration: duration,
curve: curve);
} else {
Expand All @@ -507,14 +547,13 @@ class _EHScrollablePositionedListState extends State<EHScrollablePositionedList>
SchedulerBinding.instance.addPostFrameCallback((_) {
startAnimationCallback = () {};

opacity.parent = _opacityAnimation(opacityAnimationWeights)
.animate(AnimationController(vsync: this, duration: duration)..forward());
opacity.parent = _opacityAnimation(opacityAnimationWeights).animate(AnimationController(vsync: this, duration: duration)..forward());
secondary.scrollController.jumpTo(-direction *
(_screenScrollCount * primary.scrollController.position.viewportDimension -
alignment * secondary.scrollController.position.viewportDimension));

startCompleter.complete(primary.scrollController
.animateTo(primary.scrollController.offset + direction * scrollAmount, duration: duration, curve: curve));
startCompleter.complete(
primary.scrollController.animateTo(primary.scrollController.offset + direction * scrollAmount, duration: duration, curve: curve));
endCompleter.complete(secondary.scrollController.animateTo(0, duration: duration, curve: curve));
});
};
Expand Down Expand Up @@ -576,8 +615,7 @@ class _EHScrollablePositionedListState extends State<EHScrollablePositionedList>
const endOpacity = 1.0;
return TweenSequence<double>(<TweenSequenceItem<double>>[
TweenSequenceItem<double>(tween: ConstantTween<double>(startOpacity), weight: opacityAnimationWeights[0]),
TweenSequenceItem<double>(
tween: Tween<double>(begin: startOpacity, end: endOpacity), weight: opacityAnimationWeights[1]),
TweenSequenceItem<double>(tween: Tween<double>(begin: startOpacity, end: endOpacity), weight: opacityAnimationWeights[1]),
TweenSequenceItem<double>(tween: ConstantTween<double>(endOpacity), weight: opacityAnimationWeights[2]),
]);
}
Expand All @@ -586,8 +624,8 @@ class _EHScrollablePositionedListState extends State<EHScrollablePositionedList>
final itemPositions = primary.itemPositionsNotifier.itemPositions.value
.where((ItemPosition position) => position.itemLeadingEdge < 1 && position.itemTrailingEdge > 0);
if (itemPositions.isNotEmpty) {
PageStorage.of(context).writeState(context,
itemPositions.reduce((value, element) => value.itemLeadingEdge < element.itemLeadingEdge ? value : element));
PageStorage.of(context)
.writeState(context, itemPositions.reduce((value, element) => value.itemLeadingEdge < element.itemLeadingEdge ? value : element));
}
widget.itemPositionsNotifier?.itemPositions.value = itemPositions;
}
Expand Down

0 comments on commit f9f5983

Please sign in to comment.