Skip to content

Commit e61f9e0

Browse files
authored
Fix TabBarView.viewportFraction change is ignored (#135590)
## Description This PR updates `_TabBarViewState.didUpdateWidget` in order to react to `TabBarView.viewportFraction`change. ## Related Issue Fixes flutter/flutter#135557. ## Tests Adds 1 test.
1 parent 8860dd2 commit e61f9e0

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

packages/flutter/lib/src/material/tabs.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,6 +1867,13 @@ class _TabBarViewState extends State<TabBarView> {
18671867
_currentIndex = _controller!.index;
18681868
_jumpToPage(_currentIndex!);
18691869
}
1870+
if (widget.viewportFraction != oldWidget.viewportFraction) {
1871+
_pageController?.dispose();
1872+
_pageController = PageController(
1873+
initialPage: _currentIndex!,
1874+
viewportFraction: widget.viewportFraction,
1875+
);
1876+
}
18701877
// While a warp is under way, we stop updating the tab page contents.
18711878
// This is tracked in https://github.com/flutter/flutter/issues/31269.
18721879
if (widget.children != oldWidget.children && _warpUnderwayCount == 0) {

packages/flutter/test/material/tabs_test.dart

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1643,6 +1643,54 @@ void main() {
16431643
expect(pageController.viewportFraction, 1);
16441644
});
16451645

1646+
testWidgets('TabBarView viewportFraction can be updated', (WidgetTester tester) async {
1647+
// This is a regression test for https://github.com/flutter/flutter/issues/135557.
1648+
final List<String> tabs = <String>['A', 'B', 'C'];
1649+
TabController? controller;
1650+
1651+
Widget buildFrame(double viewportFraction) {
1652+
controller = _tabController(
1653+
vsync: const TestVSync(),
1654+
length: tabs.length,
1655+
initialIndex: 1,
1656+
);
1657+
return boilerplate(
1658+
child: Column(
1659+
children: <Widget>[
1660+
TabBar(
1661+
tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
1662+
controller: controller,
1663+
),
1664+
SizedBox(
1665+
width: 400.0,
1666+
height: 400.0,
1667+
child: TabBarView(
1668+
viewportFraction: viewportFraction,
1669+
controller: controller,
1670+
children: const <Widget>[
1671+
Center(child: Text('0')),
1672+
Center(child: Text('1')),
1673+
Center(child: Text('2')),
1674+
],
1675+
),
1676+
),
1677+
],
1678+
),
1679+
);
1680+
}
1681+
1682+
await tester.pumpWidget(buildFrame(0.8));
1683+
PageView pageView = tester.widget(find.byType(PageView));
1684+
PageController pageController = pageView.controller;
1685+
expect(pageController.viewportFraction, 0.8);
1686+
1687+
// Rebuild with a different viewport fraction.
1688+
await tester.pumpWidget(buildFrame(0.5));
1689+
pageView = tester.widget(find.byType(PageView));
1690+
pageController = pageView.controller;
1691+
expect(pageController.viewportFraction, 0.5);
1692+
});
1693+
16461694
testWidgets('TabBarView has clipBehavior Clip.hardEdge by default', (WidgetTester tester) async {
16471695
final List<Widget> tabs = <Widget>[const Text('First'), const Text('Second')];
16481696

0 commit comments

Comments
 (0)