mirror of
https://github.com/flutter/flutter
synced 2024-08-25 02:46:31 +00:00
ShowCaretOnScreen is correctly scheduled within a SliverMainAxisGroup (#141671)
Fixes #141577 Fixes #135407
This commit is contained in:
parent
deaf53ef7e
commit
73c26a1c0b
|
@ -203,6 +203,30 @@ class RenderSliverMainAxisGroup extends RenderSliver with ContainerRenderObjectM
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
double? childScrollOffset(RenderObject child) {
|
||||
assert(child.parent == this);
|
||||
final GrowthDirection growthDirection = constraints.growthDirection;
|
||||
switch (growthDirection) {
|
||||
case GrowthDirection.forward:
|
||||
double childScrollOffset = 0.0;
|
||||
RenderSliver? current = childBefore(child as RenderSliver);
|
||||
while (current != null) {
|
||||
childScrollOffset += current.geometry!.scrollExtent;
|
||||
current = childBefore(current);
|
||||
}
|
||||
return childScrollOffset;
|
||||
case GrowthDirection.reverse:
|
||||
double childScrollOffset = 0.0;
|
||||
RenderSliver? current = childAfter(child as RenderSliver);
|
||||
while (current != null) {
|
||||
childScrollOffset -= current.geometry!.scrollExtent;
|
||||
current = childAfter(current);
|
||||
}
|
||||
return childScrollOffset;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
double childMainAxisPosition(RenderSliver child) {
|
||||
switch (constraints.axisDirection) {
|
||||
|
@ -254,6 +278,15 @@ class RenderSliverMainAxisGroup extends RenderSliver with ContainerRenderObjectM
|
|||
offset += childLayoutGeometry.scrollExtent;
|
||||
maxPaintExtent += child.geometry!.maxPaintExtent;
|
||||
child = childAfter(child);
|
||||
assert(() {
|
||||
if (child != null && maxPaintExtent.isInfinite) {
|
||||
throw FlutterError(
|
||||
'Unreachable sliver found, you may have a sliver behind '
|
||||
'a sliver with infinite extent. '
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}());
|
||||
}
|
||||
|
||||
final double totalScrollExtent = offset;
|
||||
|
|
|
@ -17101,6 +17101,44 @@ void main() {
|
|||
await tester.pumpAndSettle();
|
||||
expect(notifyCount, equals(1));
|
||||
});
|
||||
|
||||
testWidgets('ShowCaretOnScreen is correctly scheduled within a SliverMainAxisGroup', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
final Widget widget = MaterialApp(
|
||||
home: Scaffold(
|
||||
body: CustomScrollView(
|
||||
controller: scrollController,
|
||||
slivers: const <Widget>[
|
||||
SliverMainAxisGroup(
|
||||
slivers: <Widget>[
|
||||
SliverToBoxAdapter(
|
||||
child: SizedBox(
|
||||
height: 600,
|
||||
),
|
||||
),
|
||||
SliverToBoxAdapter(
|
||||
child: SizedBox(
|
||||
height: 44,
|
||||
child: TextField(),
|
||||
),
|
||||
),
|
||||
SliverToBoxAdapter(
|
||||
child: SizedBox(
|
||||
height: 500,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpWidget(widget);
|
||||
await tester.showKeyboard(find.byType(EditableText));
|
||||
await tester.pumpAndSettle();
|
||||
expect(scrollController.offset, 75.0);
|
||||
});
|
||||
}
|
||||
|
||||
class UnsettableController extends TextEditingController {
|
||||
|
|
|
@ -728,6 +728,23 @@ void main() {
|
|||
) as RenderSliverMainAxisGroup;
|
||||
expect(renderGroup.geometry!.cacheExtent, 850.0);
|
||||
});
|
||||
|
||||
testWidgets('SliverMainAxisGroup correctly handles ensureVisible', (WidgetTester tester) async {
|
||||
final GlobalKey key = GlobalKey();
|
||||
await tester.pumpWidget(
|
||||
_buildSliverMainAxisGroup(
|
||||
viewportHeight: 300,
|
||||
slivers: <Widget>[
|
||||
const SliverToBoxAdapter(child: SizedBox(height: 300)),
|
||||
SliverToBoxAdapter(child: SizedBox(key: key, height: 100)),
|
||||
const SliverToBoxAdapter(child: SizedBox(height: 300)),
|
||||
]
|
||||
)
|
||||
);
|
||||
Scrollable.ensureVisible(key.currentContext!);
|
||||
await tester.pumpAndSettle();
|
||||
expect(tester.getTopLeft(find.byKey(key)), Offset.zero);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildSliverList({
|
||||
|
|
Loading…
Reference in a new issue