mirror of
https://github.com/flutter/flutter
synced 2024-10-03 23:14:12 +00:00
Fix Tab
indicator image configuration doesn't inherit device pixel ratio (#146812)
fixes [The image for the indicator of the TabBar does not auto-adapt to different resolutions](https://github.com/flutter/flutter/issues/145204) ### Description This PR provides device pixel ratio to the tab indicator painter.
This commit is contained in:
parent
02400772ce
commit
f2be9bcad5
|
@ -442,6 +442,7 @@ class _IndicatorPainter extends CustomPainter {
|
|||
this.dividerColor,
|
||||
this.dividerHeight,
|
||||
required this.showDivider,
|
||||
this.devicePixelRatio,
|
||||
}) : super(repaint: controller.animation) {
|
||||
// TODO(polina-c): stop duplicating code across disposables
|
||||
// https://github.com/flutter/flutter/issues/137435
|
||||
|
@ -466,6 +467,7 @@ class _IndicatorPainter extends CustomPainter {
|
|||
final Color? dividerColor;
|
||||
final double? dividerHeight;
|
||||
final bool showDivider;
|
||||
final double? devicePixelRatio;
|
||||
|
||||
// _currentTabOffsets and _currentTextDirection are set each time TabBar
|
||||
// layout is completed. These values can be null when TabBar contains no
|
||||
|
@ -562,6 +564,7 @@ class _IndicatorPainter extends CustomPainter {
|
|||
final ImageConfiguration configuration = ImageConfiguration(
|
||||
size: _currentRect!.size,
|
||||
textDirection: _currentTextDirection,
|
||||
devicePixelRatio: devicePixelRatio,
|
||||
);
|
||||
if (showDivider && dividerHeight !> 0) {
|
||||
final Paint dividerPaint = Paint()..color = dividerColor!..strokeWidth = dividerHeight!;
|
||||
|
@ -1433,6 +1436,7 @@ class _TabBarState extends State<TabBar> {
|
|||
dividerColor: widget.dividerColor ?? tabBarTheme.dividerColor ?? _defaults.dividerColor,
|
||||
dividerHeight: widget.dividerHeight ?? tabBarTheme.dividerHeight ?? _defaults.dividerHeight,
|
||||
showDivider: theme.useMaterial3 && !widget.isScrollable,
|
||||
devicePixelRatio: MediaQuery.devicePixelRatioOf(context),
|
||||
);
|
||||
|
||||
oldPainter?.dispose();
|
||||
|
|
|
@ -50,6 +50,7 @@ Widget buildFrame({
|
|||
TextDirection textDirection = TextDirection.ltr,
|
||||
TabAlignment? tabAlignment,
|
||||
TabBarTheme? tabBarTheme,
|
||||
Decoration? indicator,
|
||||
bool? useMaterial3,
|
||||
}) {
|
||||
if (secondaryTabBar) {
|
||||
|
@ -88,6 +89,7 @@ Widget buildFrame({
|
|||
indicatorColor: indicatorColor,
|
||||
padding: padding,
|
||||
tabAlignment: tabAlignment,
|
||||
indicator: indicator,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -7075,4 +7077,50 @@ void main() {
|
|||
expect(find.text('View 0'), findsNothing);
|
||||
expect(find.text('View 2'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Tab indicator painter image configuration', (WidgetTester tester) async {
|
||||
final List<String> tabs = <String>['A', 'B'];
|
||||
final TestIndicatorDecoration decoration = TestIndicatorDecoration();
|
||||
|
||||
Widget buildTabs({
|
||||
TextDirection textDirection = TextDirection.ltr,
|
||||
double ratio = 1.0,
|
||||
}) {
|
||||
return MaterialApp(
|
||||
home: MediaQuery(
|
||||
data: MediaQueryData(devicePixelRatio: ratio),
|
||||
child: Directionality(
|
||||
textDirection: textDirection,
|
||||
child: DefaultTabController(
|
||||
length: tabs.length,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
bottom: TabBar(
|
||||
indicator: decoration,
|
||||
tabs: tabs.map((String tab) => Tab(text: tab)).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpWidget(buildTabs());
|
||||
|
||||
ImageConfiguration config = decoration.painters.last.lastConfiguration!;
|
||||
expect(config.size?.width, closeTo(14.1, 0.1));
|
||||
expect(config.size?.height, equals(48.0));
|
||||
expect(config.textDirection, TextDirection.ltr);
|
||||
expect(config.devicePixelRatio, 1.0);
|
||||
|
||||
await tester.pumpWidget(buildTabs(textDirection: TextDirection.rtl, ratio: 2.33));
|
||||
|
||||
config = decoration.painters.last.lastConfiguration!;
|
||||
expect(config.size?.width, closeTo(14.1, 0.1));
|
||||
expect(config.size?.height, equals(48.0));
|
||||
expect(config.textDirection, TextDirection.rtl);
|
||||
expect(config.devicePixelRatio, 2.33);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -228,3 +228,24 @@ class _TabAlwaysKeepAliveWidgetState extends State<TabAlwaysKeepAliveWidget> wit
|
|||
return Text(TabAlwaysKeepAliveWidget.text);
|
||||
}
|
||||
}
|
||||
|
||||
// This decoration is used to test the indicator decoration image configuration.
|
||||
class TestIndicatorDecoration extends Decoration {
|
||||
final List<TestIndicatorBoxPainter> painters = <TestIndicatorBoxPainter>[];
|
||||
|
||||
@override
|
||||
BoxPainter createBoxPainter([VoidCallback? onChanged]) {
|
||||
final TestIndicatorBoxPainter painter = TestIndicatorBoxPainter();
|
||||
painters.add(painter);
|
||||
return painter;
|
||||
}
|
||||
}
|
||||
|
||||
class TestIndicatorBoxPainter extends BoxPainter {
|
||||
ImageConfiguration? lastConfiguration;
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
|
||||
lastConfiguration = configuration;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue