Fix initial scroll of TabBar in release mode (#27568)

This commit is contained in:
Michael Goderbauer 2019-02-06 14:39:51 -08:00 committed by GitHub
parent ee30499a7e
commit e6ed069b32
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 73 additions and 1 deletions

View file

@ -476,10 +476,21 @@ class _TabBarScrollPosition extends ScrollPositionWithSingleContext {
final _TabBarState tabBar;
bool _initialViewportDimensionWasZero;
@override
bool applyContentDimensions(double minScrollExtent, double maxScrollExtent) {
bool result = true;
if (pixels == null) {
if (_initialViewportDimensionWasZero != true) {
// If the viewport never had a non-zero dimension, we just want to jump
// to the initial scroll position to avoid strange scrolling effects in
// release mode: In release mode, the viewport temporarily may have a
// dimension of zero before the actual dimension is calculated. In that
// scenario, setting the actual dimension would cause a strange scroll
// effect without this guard because the super call below would starts a
// ballistic scroll activity.
assert(viewportDimension != null);
_initialViewportDimensionWasZero = viewportDimension != 0.0;
correctPixels(tabBar._initialScrollOffset(viewportDimension, minScrollExtent, maxScrollExtent));
result = false;
}

View file

@ -2038,4 +2038,65 @@ void main() {
expect(find.text(AlwaysKeepAliveWidget.text, skipOffstage: false), findsOneWidget);
expect(find.text('4'), findsOneWidget);
});
testWidgets('tabbar does not scroll when viewport dimensions initially change from zero to non-zero', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/10531.
const List<Widget> tabs = <Widget>[
Tab(text: 'NEW MEXICO'),
Tab(text: 'GABBA'),
Tab(text: 'HEY'),
];
final TabController controller = TabController(vsync: const TestVSync(), length: tabs.length);
Widget buildTestWidget({double width, double height}) {
return MaterialApp(
home: Center(
child: SizedBox(
height: height,
width: width,
child: Scaffold(
appBar: AppBar(
title: const Text('AppBarBug'),
bottom: PreferredSize(
preferredSize: const Size.fromHeight(30.0),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Align(
alignment: FractionalOffset.center,
child: TabBar(
controller: controller,
isScrollable: true,
tabs: tabs,
),
),
),
),
),
body: const Center(
child: Text('Hello World'),
),
),
),
),
);
}
await tester.pumpWidget(
buildTestWidget(
width: 0.0,
height: 0.0,
),
);
await tester.pumpWidget(
buildTestWidget(
width: 300.0,
height: 400.0,
),
);
expect(tester.hasRunningAnimations, isFalse);
expect(await tester.pumpAndSettle(), 1); // no more frames are scheduled.
});
}