mirror of
https://github.com/flutter/flutter
synced 2024-08-24 18:36:03 +00:00
Add SingleChildScrollView
for NavigationRail
(#137415)
## Description Add `SingleChildScrollView` to `NavigationRail` for scrolling. Closes: #89167
This commit is contained in:
parent
f727948f6d
commit
fd7f45a8be
|
@ -439,39 +439,41 @@ class _NavigationRailState extends State<NavigationRail> with TickerProviderStat
|
|||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment(0, groupAlignment),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
for (int i = 0; i < widget.destinations.length; i += 1)
|
||||
_RailDestination(
|
||||
minWidth: minWidth,
|
||||
minExtendedWidth: minExtendedWidth,
|
||||
extendedTransitionAnimation: _extendedAnimation,
|
||||
selected: widget.selectedIndex == i,
|
||||
icon: widget.selectedIndex == i ? widget.destinations[i].selectedIcon : widget.destinations[i].icon,
|
||||
label: widget.destinations[i].label,
|
||||
destinationAnimation: _destinationAnimations[i],
|
||||
labelType: labelType,
|
||||
iconTheme: widget.selectedIndex == i ? selectedIconTheme : effectiveUnselectedIconTheme,
|
||||
labelTextStyle: widget.selectedIndex == i ? selectedLabelTextStyle : unselectedLabelTextStyle,
|
||||
padding: widget.destinations[i].padding,
|
||||
useIndicator: useIndicator,
|
||||
indicatorColor: useIndicator ? indicatorColor : null,
|
||||
indicatorShape: useIndicator ? indicatorShape : null,
|
||||
onTap: () {
|
||||
if (widget.onDestinationSelected != null) {
|
||||
widget.onDestinationSelected!(i);
|
||||
}
|
||||
},
|
||||
indexLabel: localizations.tabLabel(
|
||||
tabIndex: i + 1,
|
||||
tabCount: widget.destinations.length,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
for (int i = 0; i < widget.destinations.length; i += 1)
|
||||
_RailDestination(
|
||||
minWidth: minWidth,
|
||||
minExtendedWidth: minExtendedWidth,
|
||||
extendedTransitionAnimation: _extendedAnimation,
|
||||
selected: widget.selectedIndex == i,
|
||||
icon: widget.selectedIndex == i ? widget.destinations[i].selectedIcon : widget.destinations[i].icon,
|
||||
label: widget.destinations[i].label,
|
||||
destinationAnimation: _destinationAnimations[i],
|
||||
labelType: labelType,
|
||||
iconTheme: widget.selectedIndex == i ? selectedIconTheme : effectiveUnselectedIconTheme,
|
||||
labelTextStyle: widget.selectedIndex == i ? selectedLabelTextStyle : unselectedLabelTextStyle,
|
||||
padding: widget.destinations[i].padding,
|
||||
useIndicator: useIndicator,
|
||||
indicatorColor: useIndicator ? indicatorColor : null,
|
||||
indicatorShape: useIndicator ? indicatorShape : null,
|
||||
onTap: () {
|
||||
if (widget.onDestinationSelected != null) {
|
||||
widget.onDestinationSelected!(i);
|
||||
}
|
||||
},
|
||||
indexLabel: localizations.tabLabel(
|
||||
tabIndex: i + 1,
|
||||
tabCount: widget.destinations.length,
|
||||
),
|
||||
disabled: widget.destinations[i].disabled,
|
||||
),
|
||||
disabled: widget.destinations[i].disabled,
|
||||
),
|
||||
if (widget.trailing != null)
|
||||
widget.trailing!,
|
||||
],
|
||||
if (widget.trailing != null)
|
||||
widget.trailing!,
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -3605,6 +3605,62 @@ void main() {
|
|||
expect(inkFeatures, paints..circle(color: Colors.transparent));
|
||||
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/99933
|
||||
|
||||
testWidgets('NavigationRail can scroll in low height', (WidgetTester tester) async {
|
||||
// This is a regression test for https://github.com/flutter/flutter/issues/89167.
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeData(
|
||||
useMaterial3: true,
|
||||
),
|
||||
home: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return MediaQuery(
|
||||
// Set Screen height with 300
|
||||
data: MediaQuery.of(context).copyWith(size: const Size(800, 300)),
|
||||
child: Scaffold(
|
||||
body: Row(
|
||||
children: <Widget>[
|
||||
// Set NavigationRail height with 100
|
||||
SizedBox(
|
||||
height: 100,
|
||||
child: NavigationRail(
|
||||
selectedIndex: 0,
|
||||
destinations: const <NavigationRailDestination>[
|
||||
NavigationRailDestination(
|
||||
icon: Icon(Icons.favorite_border),
|
||||
selectedIcon: Icon(Icons.favorite),
|
||||
label: Text('Abc'),
|
||||
),
|
||||
NavigationRailDestination(
|
||||
icon: Icon(Icons.bookmark_border),
|
||||
selectedIcon: Icon(Icons.bookmark),
|
||||
label: Text('Def'),
|
||||
),
|
||||
NavigationRailDestination(
|
||||
icon: Icon(Icons.star_border),
|
||||
selectedIcon: Icon(Icons.star),
|
||||
label: Text('Ghi'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Expanded(
|
||||
child: Text('body'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final ScrollableState scrollable = tester.state(find.byType(Scrollable));
|
||||
scrollable.position.jumpTo(500.0);
|
||||
expect(scrollable.position.pixels, equals(500.0));
|
||||
});
|
||||
|
||||
group('Material 2', () {
|
||||
// These tests are only relevant for Material 2. Once Material 2
|
||||
// support is deprecated and the APIs are removed, these tests
|
||||
|
@ -5433,31 +5489,34 @@ TestSemantics _expectedSemantics() {
|
|||
flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
|
||||
children: <TestSemantics>[
|
||||
TestSemantics(
|
||||
flags: <SemanticsFlag>[
|
||||
SemanticsFlag.isSelected,
|
||||
SemanticsFlag.isFocusable,
|
||||
flags: <SemanticsFlag>[SemanticsFlag.hasImplicitScrolling],
|
||||
children: <TestSemantics>[
|
||||
TestSemantics(
|
||||
flags: <SemanticsFlag>[SemanticsFlag.isSelected,
|
||||
SemanticsFlag.isFocusable],
|
||||
actions: <SemanticsAction>[SemanticsAction.tap],
|
||||
label: 'Abc\nTab 1 of 4',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
TestSemantics(
|
||||
flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
|
||||
actions: <SemanticsAction>[SemanticsAction.tap],
|
||||
label: 'Def\nTab 2 of 4',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
TestSemantics(
|
||||
flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
|
||||
actions: <SemanticsAction>[SemanticsAction.tap],
|
||||
label: 'Ghi\nTab 3 of 4',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
TestSemantics(
|
||||
flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
|
||||
actions: <SemanticsAction>[SemanticsAction.tap],
|
||||
label: 'Jkl\nTab 4 of 4',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
],
|
||||
actions: <SemanticsAction>[SemanticsAction.tap],
|
||||
label: 'Abc\nTab 1 of 4',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
TestSemantics(
|
||||
flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
|
||||
actions: <SemanticsAction>[SemanticsAction.tap],
|
||||
label: 'Def\nTab 2 of 4',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
TestSemantics(
|
||||
flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
|
||||
actions: <SemanticsAction>[SemanticsAction.tap],
|
||||
label: 'Ghi\nTab 3 of 4',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
TestSemantics(
|
||||
flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
|
||||
actions: <SemanticsAction>[SemanticsAction.tap],
|
||||
label: 'Jkl\nTab 4 of 4',
|
||||
textDirection: TextDirection.ltr,
|
||||
),
|
||||
TestSemantics(
|
||||
label: 'body',
|
||||
|
|
Loading…
Reference in a new issue