Unverified Commit a0bfde9b authored by Kate Lovett's avatar Kate Lovett Committed by GitHub

Fix ensureVisible and default focus traversal for reversed scrollables (#128756)

Fixes https://github.com/flutter/flutter/issues/128749

The ScrollPositionAlignmentPolicy does not account for AxisDirection, which meant default focus traversal of reversed scrollables did not work. The policy doesn't know about the axis direction, so this is corrected in the ScrollPosition where all the information is available before calling on the viewport for the new target scroll offset.

This fixes that by flipping the policy (unless explicit) so that focus traversal works.
parent 79bdc6dd
......@@ -757,6 +757,26 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
context.setSemanticsActions(_semanticActions!);
}
ScrollPositionAlignmentPolicy _maybeFlipAlignment(ScrollPositionAlignmentPolicy alignmentPolicy) {
return switch (alignmentPolicy) {
// Don't flip when explicit.
ScrollPositionAlignmentPolicy.explicit => alignmentPolicy,
ScrollPositionAlignmentPolicy.keepVisibleAtEnd => ScrollPositionAlignmentPolicy.keepVisibleAtStart,
ScrollPositionAlignmentPolicy.keepVisibleAtStart => ScrollPositionAlignmentPolicy.keepVisibleAtEnd,
};
}
ScrollPositionAlignmentPolicy _applyAxisDirectionToAlignmentPolicy(ScrollPositionAlignmentPolicy alignmentPolicy) {
return switch (axisDirection) {
// Start and end alignments must account for axis direction.
// When focus is requested for example, it knows the directionality of the
// keyboard keys initiating traversal, but not the direction of the
// Scrollable.
AxisDirection.up || AxisDirection.left => _maybeFlipAlignment(alignmentPolicy),
AxisDirection.down || AxisDirection.right => alignmentPolicy,
};
}
/// Animates the position such that the given object is as visible as possible
/// by just scrolling this position.
///
......@@ -790,7 +810,7 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
}
double target;
switch (alignmentPolicy) {
switch (_applyAxisDirectionToAlignmentPolicy(alignmentPolicy)) {
case ScrollPositionAlignmentPolicy.explicit:
target = clampDouble(viewport.getOffsetToReveal(object, alignment, rect: targetRect).offset, minScrollExtent, maxScrollExtent);
case ScrollPositionAlignmentPolicy.keepVisibleAtEnd:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment