mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Fix getOffsetToReveal for growthDirection reversed and AxisDirection down or right (#38441)
* Take growth direction into account when computing value for getOffsetForReveal in AxisDirection.right and .up conditions. * Add alignment 1.0 test to left - reverse growth * Add Reverse List showOnScreen test * Formatting fix.
This commit is contained in:
parent
f1003d536d
commit
1d03459fdb
@ -649,11 +649,29 @@ abstract class RenderViewportBase<ParentDataClass extends ContainerParentDataMix
|
|||||||
targetMainAxisExtent = bounds.height;
|
targetMainAxisExtent = bounds.height;
|
||||||
break;
|
break;
|
||||||
case AxisDirection.right:
|
case AxisDirection.right:
|
||||||
leadingScrollOffset += bounds.left;
|
double offset;
|
||||||
|
switch (growthDirection) {
|
||||||
|
case GrowthDirection.forward:
|
||||||
|
offset = bounds.left;
|
||||||
|
break;
|
||||||
|
case GrowthDirection.reverse:
|
||||||
|
offset = bounds.right;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
leadingScrollOffset += offset;
|
||||||
targetMainAxisExtent = bounds.width;
|
targetMainAxisExtent = bounds.width;
|
||||||
break;
|
break;
|
||||||
case AxisDirection.down:
|
case AxisDirection.down:
|
||||||
leadingScrollOffset += bounds.top;
|
double offset;
|
||||||
|
switch (growthDirection) {
|
||||||
|
case GrowthDirection.forward:
|
||||||
|
offset = bounds.top;
|
||||||
|
break;
|
||||||
|
case GrowthDirection.reverse:
|
||||||
|
offset = bounds.bottom;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
leadingScrollOffset += offset;
|
||||||
targetMainAxisExtent = bounds.height;
|
targetMainAxisExtent = bounds.height;
|
||||||
break;
|
break;
|
||||||
case AxisDirection.left:
|
case AxisDirection.left:
|
||||||
|
@ -314,6 +314,107 @@ void main() {
|
|||||||
expect(revealed.offset, 5 * (100 + 22 + 22) + 22 - 100);
|
expect(revealed.offset, 5 * (100 + 22 + 22) + 22 - 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('Viewport getOffsetToReveal Sliver - up - reverse growth', (WidgetTester tester) async {
|
||||||
|
const Key centerKey = ValueKey<String>('center');
|
||||||
|
final Widget centerSliver = SliverPadding(
|
||||||
|
key: centerKey,
|
||||||
|
padding: const EdgeInsets.all(22.0),
|
||||||
|
sliver: SliverToBoxAdapter(
|
||||||
|
child: Container(
|
||||||
|
height: 100.0,
|
||||||
|
child: const Text('Tile center'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
final Widget lowerItem = Container(
|
||||||
|
height: 100.0,
|
||||||
|
child: const Text('Tile lower'),
|
||||||
|
);
|
||||||
|
final Widget lowerSliver = SliverPadding(
|
||||||
|
padding: const EdgeInsets.all(22.0),
|
||||||
|
sliver: SliverToBoxAdapter(
|
||||||
|
child: lowerItem,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: Center(
|
||||||
|
child: Container(
|
||||||
|
height: 200.0,
|
||||||
|
width: 300.0,
|
||||||
|
child: CustomScrollView(
|
||||||
|
center: centerKey,
|
||||||
|
reverse: true,
|
||||||
|
slivers: <Widget>[lowerSliver, centerSliver],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final RenderAbstractViewport viewport = tester.allRenderObjects.firstWhere((RenderObject r) => r is RenderAbstractViewport);
|
||||||
|
|
||||||
|
final RenderObject target = tester.renderObject(find.byWidget(lowerItem, skipOffstage: false));
|
||||||
|
RevealedOffset revealed = viewport.getOffsetToReveal(target, 0.0);
|
||||||
|
expect(revealed.offset, - 100 - 22);
|
||||||
|
|
||||||
|
revealed = viewport.getOffsetToReveal(target, 1.0);
|
||||||
|
expect(revealed.offset, - 100 - 22 - 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Viewport getOffsetToReveal Sliver - left - reverse growth', (WidgetTester tester) async {
|
||||||
|
const Key centerKey = ValueKey<String>('center');
|
||||||
|
final Widget centerSliver = SliverPadding(
|
||||||
|
key: centerKey,
|
||||||
|
padding: const EdgeInsets.all(22.0),
|
||||||
|
sliver: SliverToBoxAdapter(
|
||||||
|
child: Container(
|
||||||
|
width: 100.0,
|
||||||
|
child: const Text('Tile center'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
final Widget lowerItem = Container(
|
||||||
|
width: 100.0,
|
||||||
|
child: const Text('Tile lower'),
|
||||||
|
);
|
||||||
|
final Widget lowerSliver = SliverPadding(
|
||||||
|
padding: const EdgeInsets.all(22.0),
|
||||||
|
sliver: SliverToBoxAdapter(
|
||||||
|
child: lowerItem,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: Center(
|
||||||
|
child: Container(
|
||||||
|
height: 200.0,
|
||||||
|
width: 300.0,
|
||||||
|
child: CustomScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
center: centerKey,
|
||||||
|
reverse: true,
|
||||||
|
slivers: <Widget>[lowerSliver, centerSliver],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final RenderAbstractViewport viewport = tester.allRenderObjects.firstWhere((RenderObject r) => r is RenderAbstractViewport);
|
||||||
|
|
||||||
|
final RenderObject target = tester.renderObject(find.byWidget(lowerItem, skipOffstage: false));
|
||||||
|
RevealedOffset revealed = viewport.getOffsetToReveal(target, 0.0);
|
||||||
|
expect(revealed.offset, -100 - 22);
|
||||||
|
|
||||||
|
revealed = viewport.getOffsetToReveal(target, 1.0);
|
||||||
|
expect(revealed.offset, - 100 - 22 - 200);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('Viewport getOffsetToReveal Sliver - left', (WidgetTester tester) async {
|
testWidgets('Viewport getOffsetToReveal Sliver - left', (WidgetTester tester) async {
|
||||||
final List<Widget> children = <Widget>[];
|
final List<Widget> children = <Widget>[];
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
@ -556,6 +657,71 @@ void main() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testWidgets('Reverse List showOnScreen', (WidgetTester tester) async {
|
||||||
|
const double screenHeight = 400.0;
|
||||||
|
const double screenWidth = 400.0;
|
||||||
|
const double itemHeight = screenHeight / 10.0;
|
||||||
|
const ValueKey<String> centerKey = ValueKey<String>('center');
|
||||||
|
|
||||||
|
tester.binding.window.devicePixelRatioTestValue = 1.0;
|
||||||
|
tester.binding.window.physicalSizeTestValue = const Size(screenWidth, screenHeight);
|
||||||
|
|
||||||
|
await tester.pumpWidget(Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: CustomScrollView(
|
||||||
|
center: centerKey,
|
||||||
|
reverse: true,
|
||||||
|
slivers: <Widget>[
|
||||||
|
SliverList(
|
||||||
|
delegate: SliverChildListDelegate(
|
||||||
|
List<Widget>.generate(
|
||||||
|
10,
|
||||||
|
(int index) => SizedBox(
|
||||||
|
height: itemHeight,
|
||||||
|
child: Text('Item ${-index - 1}'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SliverList(
|
||||||
|
key: centerKey,
|
||||||
|
delegate: SliverChildListDelegate(
|
||||||
|
List<Widget>.generate(
|
||||||
|
1,
|
||||||
|
(int index) => const SizedBox(
|
||||||
|
height: itemHeight,
|
||||||
|
child: Text('Item 0'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SliverList(
|
||||||
|
delegate: SliverChildListDelegate(
|
||||||
|
List<Widget>.generate(
|
||||||
|
10,
|
||||||
|
(int index) => SizedBox(
|
||||||
|
height: itemHeight,
|
||||||
|
child: Text('Item ${index + 1}'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(find.text('Item -1'), findsNothing);
|
||||||
|
|
||||||
|
final RenderBox itemNeg1 =
|
||||||
|
tester.renderObject(find.text('Item -1', skipOffstage: false));
|
||||||
|
|
||||||
|
itemNeg1.showOnScreen(duration: const Duration(seconds: 1));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
expect(find.text('Item -1'), findsOneWidget);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('in view in inner, but not in outer', (WidgetTester tester) async {
|
testWidgets('in view in inner, but not in outer', (WidgetTester tester) async {
|
||||||
final ScrollController inner = ScrollController();
|
final ScrollController inner = ScrollController();
|
||||||
final ScrollController outer = ScrollController();
|
final ScrollController outer = ScrollController();
|
||||||
|
Loading…
Reference in New Issue
Block a user