Unverified Commit f37c235c authored by MH Johnson's avatar MH Johnson Committed by GitHub

[Material] Add TabBarTheme (#22012)

* Add tab bar theme.

* Add tab bar theme.

* Add tests, pass context to getters.

* update goldens from linux box

* update goldens from linux box

* Added new golden test, addressed comments

* override hashCode and == in TabBarTheme

* Fix comment typos

* Addressed Hans' comments.

* Formatting changes

* [TabBarTheme] Fixed spacing

* [TabBarTheme] Update goldens version to latest commit
parent 6c00bf98
a7f6061b8171f6fc82b6f437d13079ee26189438 b84f87078729d0af8380fd9826091d8bafe6fcc7
...@@ -88,6 +88,7 @@ export 'src/material/snack_bar.dart'; ...@@ -88,6 +88,7 @@ export 'src/material/snack_bar.dart';
export 'src/material/stepper.dart'; export 'src/material/stepper.dart';
export 'src/material/switch.dart'; export 'src/material/switch.dart';
export 'src/material/switch_list_tile.dart'; export 'src/material/switch_list_tile.dart';
export 'src/material/tab_bar_theme.dart';
export 'src/material/tab_controller.dart'; export 'src/material/tab_controller.dart';
export 'src/material/tab_indicator.dart'; export 'src/material/tab_indicator.dart';
export 'src/material/tabs.dart'; export 'src/material/tabs.dart';
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
import 'tabs.dart';
/// Defines a theme for [TabBar] widgets.
///
/// A tab bar theme describes the color of the tab label and the size/shape of
/// the [TabBar.indicator].
///
/// Descendant widgets obtain the current theme's [TabBarTheme] object using
/// `Theme.of(context).tabBarTheme`.
/// [ThemeData.tabBarTheme] can be customized by copying it (using
/// [TabBarTheme.copyWith]).
///
/// See also:
///
/// * [TabBar], a widget that displays a horizontal row of tabs.
/// * [ThemeData], which describes the overall theme information for the
/// application.
class TabBarTheme extends Diagnosticable {
/// Creates a tab bar theme that can be used with [ThemeData.tabBarTheme].
const TabBarTheme({
this.indicator,
this.indicatorSize,
this.labelColor,
this.unselectedLabelColor,
});
/// Default value for [TabBar.indicator].
final Decoration indicator;
/// Default value for [TabBar.indicatorSize].
final TabBarIndicatorSize indicatorSize;
/// Default value for [TabBar.labelColor].
final Color labelColor;
/// Default value for [TabBar.unselectedLabelColor].
final Color unselectedLabelColor;
/// Creates a copy of this object but with the given fields replaced with the
/// new values.
TabBarTheme copyWith({
Decoration indicator,
TabBarIndicatorSize indicatorSize,
Color labelColor,
Color unselectedLabelColor,
}) {
return TabBarTheme(
indicator: indicator ?? this.indicator,
indicatorSize: indicatorSize ?? this.indicatorSize,
labelColor: labelColor ?? this.labelColor,
unselectedLabelColor: unselectedLabelColor ?? this.unselectedLabelColor
);
}
/// Linearly interpolate between two tab bar themes.
///
/// {@macro flutter.material.themeData.lerp}
static TabBarTheme lerp(TabBarTheme a, TabBarTheme b, double t) {
assert(a != null);
assert(b != null);
assert(t != null);
return TabBarTheme(
indicator: Decoration.lerp(a.indicator, b.indicator, t),
indicatorSize: t < 0.5 ? a.indicatorSize : b.indicatorSize,
labelColor: Color.lerp(a.labelColor, b.labelColor, t),
unselectedLabelColor: Color.lerp(a.unselectedLabelColor, b.unselectedLabelColor, t)
);
}
@override
int get hashCode {
return hashValues(indicator, indicatorSize, labelColor, unselectedLabelColor);
}
@override
bool operator ==(dynamic other) {
if (identical(this, other))
return true;
if (other.runtimeType != runtimeType)
return false;
final TabBarTheme typedOther = other;
return typedOther.indicator == indicator
&& typedOther.indicatorSize == indicatorSize
&& typedOther.labelColor == labelColor
&& typedOther.unselectedLabelColor == unselectedLabelColor;
}
}
...@@ -15,6 +15,7 @@ import 'debug.dart'; ...@@ -15,6 +15,7 @@ import 'debug.dart';
import 'ink_well.dart'; import 'ink_well.dart';
import 'material.dart'; import 'material.dart';
import 'material_localizations.dart'; import 'material_localizations.dart';
import 'tab_bar_theme.dart';
import 'tab_controller.dart'; import 'tab_controller.dart';
import 'tab_indicator.dart'; import 'tab_indicator.dart';
import 'theme.dart'; import 'theme.dart';
...@@ -149,14 +150,22 @@ class _TabStyle extends AnimatedWidget { ...@@ -149,14 +150,22 @@ class _TabStyle extends AnimatedWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context); final ThemeData themeData = Theme.of(context);
final TabBarTheme tabBarTheme = themeData.tabBarTheme;
final TextStyle defaultStyle = labelStyle ?? themeData.primaryTextTheme.body2; final TextStyle defaultStyle = labelStyle ?? themeData.primaryTextTheme.body2;
final TextStyle defaultUnselectedStyle = unselectedLabelStyle ?? labelStyle ?? themeData.primaryTextTheme.body2; final TextStyle defaultUnselectedStyle = unselectedLabelStyle ?? labelStyle ?? themeData.primaryTextTheme.body2;
final Animation<double> animation = listenable; final Animation<double> animation = listenable;
final TextStyle textStyle = selected final TextStyle textStyle = selected
? TextStyle.lerp(defaultStyle, defaultUnselectedStyle, animation.value) ? TextStyle.lerp(defaultStyle, defaultUnselectedStyle, animation.value)
: TextStyle.lerp(defaultUnselectedStyle, defaultStyle, animation.value); : TextStyle.lerp(defaultUnselectedStyle, defaultStyle, animation.value);
final Color selectedColor = labelColor ?? themeData.primaryTextTheme.body2.color; final Color selectedColor =
final Color unselectedColor = unselectedLabelColor ?? selectedColor.withAlpha(0xB2); // 70% alpha labelColor
?? tabBarTheme.labelColor
?? themeData.primaryTextTheme.body2.color;
final Color unselectedColor =
unselectedLabelColor
?? tabBarTheme.unselectedLabelColor
?? selectedColor.withAlpha(0xB2); // 70% alpha
final Color color = selected final Color color = selected
? Color.lerp(selectedColor, unselectedColor, animation.value) ? Color.lerp(selectedColor, unselectedColor, animation.value)
: Color.lerp(unselectedColor, selectedColor, animation.value); : Color.lerp(unselectedColor, selectedColor, animation.value);
...@@ -504,6 +513,8 @@ class _TabBarScrollController extends ScrollController { ...@@ -504,6 +513,8 @@ class _TabBarScrollController extends ScrollController {
/// ///
/// Requires one of its ancestors to be a [Material] widget. /// Requires one of its ancestors to be a [Material] widget.
/// ///
/// Uses values from [ThemeData.tabBarTheme] if it is set in the current context.
///
/// See also: /// See also:
/// ///
/// * [TabBarView], which displays page views that correspond to each tab. /// * [TabBarView], which displays page views that correspond to each tab.
...@@ -687,8 +698,11 @@ class _TabBarState extends State<TabBar> { ...@@ -687,8 +698,11 @@ class _TabBarState extends State<TabBar> {
Decoration get _indicator { Decoration get _indicator {
if (widget.indicator != null) if (widget.indicator != null)
return widget.indicator; return widget.indicator;
final ThemeData themeData = Theme.of(context);
if (themeData.tabBarTheme.indicator != null)
return themeData.tabBarTheme.indicator;
Color color = widget.indicatorColor ?? Theme.of(context).indicatorColor; Color color = widget.indicatorColor ?? themeData.indicatorColor;
// ThemeData tries to avoid this by having indicatorColor avoid being the // ThemeData tries to avoid this by having indicatorColor avoid being the
// primaryColor. However, it's possible that the tab bar is on a // primaryColor. However, it's possible that the tab bar is on a
// Material that isn't the primaryColor. In that case, if the indicator // Material that isn't the primaryColor. In that case, if the indicator
...@@ -741,7 +755,7 @@ class _TabBarState extends State<TabBar> { ...@@ -741,7 +755,7 @@ class _TabBarState extends State<TabBar> {
_indicatorPainter = _controller == null ? null : _IndicatorPainter( _indicatorPainter = _controller == null ? null : _IndicatorPainter(
controller: _controller, controller: _controller,
indicator: _indicator, indicator: _indicator,
indicatorSize: widget.indicatorSize, indicatorSize: widget.indicatorSize ?? Theme.of(context).tabBarTheme.indicatorSize,
tabKeys: _tabKeys, tabKeys: _tabKeys,
old: _indicatorPainter, old: _indicatorPainter,
); );
......
...@@ -16,6 +16,7 @@ import 'ink_well.dart' show InteractiveInkFeatureFactory; ...@@ -16,6 +16,7 @@ import 'ink_well.dart' show InteractiveInkFeatureFactory;
import 'input_decorator.dart'; import 'input_decorator.dart';
import 'page_transitions_theme.dart'; import 'page_transitions_theme.dart';
import 'slider_theme.dart'; import 'slider_theme.dart';
import 'tab_bar_theme.dart';
import 'typography.dart'; import 'typography.dart';
export 'package:flutter/services.dart' show Brightness; export 'package:flutter/services.dart' show Brightness;
...@@ -141,6 +142,7 @@ class ThemeData extends Diagnosticable { ...@@ -141,6 +142,7 @@ class ThemeData extends Diagnosticable {
IconThemeData primaryIconTheme, IconThemeData primaryIconTheme,
IconThemeData accentIconTheme, IconThemeData accentIconTheme,
SliderThemeData sliderTheme, SliderThemeData sliderTheme,
TabBarTheme tabBarTheme,
ChipThemeData chipTheme, ChipThemeData chipTheme,
TargetPlatform platform, TargetPlatform platform,
MaterialTapTargetSize materialTapTargetSize, MaterialTapTargetSize materialTapTargetSize,
...@@ -185,6 +187,7 @@ class ThemeData extends Diagnosticable { ...@@ -185,6 +187,7 @@ class ThemeData extends Diagnosticable {
errorColor ??= Colors.red[700]; errorColor ??= Colors.red[700];
inputDecorationTheme ??= const InputDecorationTheme(); inputDecorationTheme ??= const InputDecorationTheme();
pageTransitionsTheme ??= const PageTransitionsTheme(); pageTransitionsTheme ??= const PageTransitionsTheme();
tabBarTheme ??= const TabBarTheme();
primaryIconTheme ??= primaryIsDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black); primaryIconTheme ??= primaryIsDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black);
accentIconTheme ??= accentIsDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black); accentIconTheme ??= accentIsDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black);
iconTheme ??= isDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black87); iconTheme ??= isDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black87);
...@@ -207,6 +210,7 @@ class ThemeData extends Diagnosticable { ...@@ -207,6 +210,7 @@ class ThemeData extends Diagnosticable {
primaryColorDark: primaryColorDark, primaryColorDark: primaryColorDark,
valueIndicatorTextStyle: accentTextTheme.body2, valueIndicatorTextStyle: accentTextTheme.body2,
); );
tabBarTheme ??= const TabBarTheme();
chipTheme ??= ChipThemeData.fromDefaults( chipTheme ??= ChipThemeData.fromDefaults(
secondaryColor: primaryColor, secondaryColor: primaryColor,
brightness: brightness, brightness: brightness,
...@@ -252,6 +256,7 @@ class ThemeData extends Diagnosticable { ...@@ -252,6 +256,7 @@ class ThemeData extends Diagnosticable {
primaryIconTheme: primaryIconTheme, primaryIconTheme: primaryIconTheme,
accentIconTheme: accentIconTheme, accentIconTheme: accentIconTheme,
sliderTheme: sliderTheme, sliderTheme: sliderTheme,
tabBarTheme: tabBarTheme,
chipTheme: chipTheme, chipTheme: chipTheme,
platform: platform, platform: platform,
materialTapTargetSize: materialTapTargetSize, materialTapTargetSize: materialTapTargetSize,
...@@ -307,6 +312,7 @@ class ThemeData extends Diagnosticable { ...@@ -307,6 +312,7 @@ class ThemeData extends Diagnosticable {
@required this.primaryIconTheme, @required this.primaryIconTheme,
@required this.accentIconTheme, @required this.accentIconTheme,
@required this.sliderTheme, @required this.sliderTheme,
@required this.tabBarTheme,
@required this.chipTheme, @required this.chipTheme,
@required this.platform, @required this.platform,
@required this.materialTapTargetSize, @required this.materialTapTargetSize,
...@@ -348,6 +354,7 @@ class ThemeData extends Diagnosticable { ...@@ -348,6 +354,7 @@ class ThemeData extends Diagnosticable {
assert(primaryIconTheme != null), assert(primaryIconTheme != null),
assert(accentIconTheme != null), assert(accentIconTheme != null),
assert(sliderTheme != null), assert(sliderTheme != null),
assert(tabBarTheme != null),
assert(chipTheme != null), assert(chipTheme != null),
assert(platform != null), assert(platform != null),
assert(materialTapTargetSize != null), assert(materialTapTargetSize != null),
...@@ -533,6 +540,9 @@ class ThemeData extends Diagnosticable { ...@@ -533,6 +540,9 @@ class ThemeData extends Diagnosticable {
/// This is the value returned from [SliderTheme.of]. /// This is the value returned from [SliderTheme.of].
final SliderThemeData sliderTheme; final SliderThemeData sliderTheme;
/// A theme for customizing the size, shape, and color of the tab bar indicator.
final TabBarTheme tabBarTheme;
/// The colors and styles used to render [Chip], [ /// The colors and styles used to render [Chip], [
/// ///
/// This is the value returned from [ChipTheme.of]. /// This is the value returned from [ChipTheme.of].
...@@ -600,6 +610,7 @@ class ThemeData extends Diagnosticable { ...@@ -600,6 +610,7 @@ class ThemeData extends Diagnosticable {
IconThemeData primaryIconTheme, IconThemeData primaryIconTheme,
IconThemeData accentIconTheme, IconThemeData accentIconTheme,
SliderThemeData sliderTheme, SliderThemeData sliderTheme,
TabBarTheme tabBarTheme,
ChipThemeData chipTheme, ChipThemeData chipTheme,
TargetPlatform platform, TargetPlatform platform,
MaterialTapTargetSize materialTapTargetSize, MaterialTapTargetSize materialTapTargetSize,
...@@ -644,6 +655,7 @@ class ThemeData extends Diagnosticable { ...@@ -644,6 +655,7 @@ class ThemeData extends Diagnosticable {
primaryIconTheme: primaryIconTheme ?? this.primaryIconTheme, primaryIconTheme: primaryIconTheme ?? this.primaryIconTheme,
accentIconTheme: accentIconTheme ?? this.accentIconTheme, accentIconTheme: accentIconTheme ?? this.accentIconTheme,
sliderTheme: sliderTheme ?? this.sliderTheme, sliderTheme: sliderTheme ?? this.sliderTheme,
tabBarTheme: tabBarTheme ?? this.tabBarTheme,
chipTheme: chipTheme ?? this.chipTheme, chipTheme: chipTheme ?? this.chipTheme,
platform: platform ?? this.platform, platform: platform ?? this.platform,
materialTapTargetSize: materialTapTargetSize ?? this.materialTapTargetSize, materialTapTargetSize: materialTapTargetSize ?? this.materialTapTargetSize,
...@@ -718,6 +730,7 @@ class ThemeData extends Diagnosticable { ...@@ -718,6 +730,7 @@ class ThemeData extends Diagnosticable {
/// Linearly interpolate between two themes. /// Linearly interpolate between two themes.
/// ///
/// {@template flutter.material.themeData.lerp}
/// The arguments must not be null. /// The arguments must not be null.
/// ///
/// The `t` argument represents position on the timeline, with 0.0 meaning /// The `t` argument represents position on the timeline, with 0.0 meaning
...@@ -731,6 +744,7 @@ class ThemeData extends Diagnosticable { ...@@ -731,6 +744,7 @@ class ThemeData extends Diagnosticable {
/// ///
/// Values for `t` are usually obtained from an [Animation<double>], such as /// Values for `t` are usually obtained from an [Animation<double>], such as
/// an [AnimationController]. /// an [AnimationController].
/// {@endtemplate}
static ThemeData lerp(ThemeData a, ThemeData b, double t) { static ThemeData lerp(ThemeData a, ThemeData b, double t) {
assert(a != null); assert(a != null);
assert(b != null); assert(b != null);
...@@ -774,6 +788,7 @@ class ThemeData extends Diagnosticable { ...@@ -774,6 +788,7 @@ class ThemeData extends Diagnosticable {
primaryIconTheme: IconThemeData.lerp(a.primaryIconTheme, b.primaryIconTheme, t), primaryIconTheme: IconThemeData.lerp(a.primaryIconTheme, b.primaryIconTheme, t),
accentIconTheme: IconThemeData.lerp(a.accentIconTheme, b.accentIconTheme, t), accentIconTheme: IconThemeData.lerp(a.accentIconTheme, b.accentIconTheme, t),
sliderTheme: SliderThemeData.lerp(a.sliderTheme, b.sliderTheme, t), sliderTheme: SliderThemeData.lerp(a.sliderTheme, b.sliderTheme, t),
tabBarTheme: TabBarTheme.lerp(a.tabBarTheme, b.tabBarTheme, t),
chipTheme: ChipThemeData.lerp(a.chipTheme, b.chipTheme, t), chipTheme: ChipThemeData.lerp(a.chipTheme, b.chipTheme, t),
platform: t < 0.5 ? a.platform : b.platform, platform: t < 0.5 ? a.platform : b.platform,
materialTapTargetSize: t < 0.5 ? a.materialTapTargetSize : b.materialTapTargetSize, materialTapTargetSize: t < 0.5 ? a.materialTapTargetSize : b.materialTapTargetSize,
...@@ -827,6 +842,7 @@ class ThemeData extends Diagnosticable { ...@@ -827,6 +842,7 @@ class ThemeData extends Diagnosticable {
(otherData.primaryIconTheme == primaryIconTheme) && (otherData.primaryIconTheme == primaryIconTheme) &&
(otherData.accentIconTheme == accentIconTheme) && (otherData.accentIconTheme == accentIconTheme) &&
(otherData.sliderTheme == sliderTheme) && (otherData.sliderTheme == sliderTheme) &&
(otherData.tabBarTheme == tabBarTheme) &&
(otherData.chipTheme == chipTheme) && (otherData.chipTheme == chipTheme) &&
(otherData.platform == platform) && (otherData.platform == platform) &&
(otherData.materialTapTargetSize == materialTapTargetSize) && (otherData.materialTapTargetSize == materialTapTargetSize) &&
...@@ -883,6 +899,7 @@ class ThemeData extends Diagnosticable { ...@@ -883,6 +899,7 @@ class ThemeData extends Diagnosticable {
platform, platform,
materialTapTargetSize, materialTapTargetSize,
pageTransitionsTheme, pageTransitionsTheme,
tabBarTheme,
), ),
), ),
); );
...@@ -928,6 +945,7 @@ class ThemeData extends Diagnosticable { ...@@ -928,6 +945,7 @@ class ThemeData extends Diagnosticable {
properties.add(DiagnosticsProperty<IconThemeData>('primaryIconTheme', primaryIconTheme)); properties.add(DiagnosticsProperty<IconThemeData>('primaryIconTheme', primaryIconTheme));
properties.add(DiagnosticsProperty<IconThemeData>('accentIconTheme', accentIconTheme)); properties.add(DiagnosticsProperty<IconThemeData>('accentIconTheme', accentIconTheme));
properties.add(DiagnosticsProperty<SliderThemeData>('sliderTheme', sliderTheme)); properties.add(DiagnosticsProperty<SliderThemeData>('sliderTheme', sliderTheme));
properties.add(DiagnosticsProperty<TabBarTheme>('tabBarTheme', tabBarTheme));
properties.add(DiagnosticsProperty<ChipThemeData>('chipTheme', chipTheme)); properties.add(DiagnosticsProperty<ChipThemeData>('chipTheme', chipTheme));
properties.add(DiagnosticsProperty<MaterialTapTargetSize>('materialTapTargetSize', materialTapTargetSize)); properties.add(DiagnosticsProperty<MaterialTapTargetSize>('materialTapTargetSize', materialTapTargetSize));
properties.add(DiagnosticsProperty<PageTransitionsTheme>('pageTransitionsTheme', pageTransitionsTheme)); properties.add(DiagnosticsProperty<PageTransitionsTheme>('pageTransitionsTheme', pageTransitionsTheme));
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:io' show Platform;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
const String _tab1Text = 'tab 1';
const String _tab2Text = 'tab 2';
const String _tab3Text = 'tab 3';
final Key _painterKey = UniqueKey();
const List<Tab> _tabs = <Tab>[
Tab(text: _tab1Text, icon: Icon(Icons.looks_one)),
Tab(text: _tab2Text, icon: Icon(Icons.looks_two)),
Tab(text: _tab3Text, icon: Icon(Icons.looks_3)),
];
Widget _buildTabBar({ List<Tab> tabs = _tabs }) {
final TabController _tabController = TabController(length: 3, vsync: const TestVSync());
return RepaintBoundary(
key: _painterKey,
child: TabBar(tabs: tabs, controller: _tabController),
);
}
Widget _withTheme(TabBarTheme theme) {
return MaterialApp(
theme: ThemeData(tabBarTheme: theme),
home: Scaffold(body: _buildTabBar()),
);
}
RenderParagraph _iconRenderObject(WidgetTester tester, IconData icon) {
return tester.renderObject<RenderParagraph>(
find.descendant(of: find.byIcon(icon), matching: find.byType(RichText)));
}
void main() {
testWidgets('Tab bar theme overrides label color (selected)', (WidgetTester tester) async {
const Color labelColor = Colors.black;
const TabBarTheme tabBarTheme = TabBarTheme(labelColor: labelColor);
await tester.pumpWidget(_withTheme(tabBarTheme));
final RenderParagraph textRenderObject = tester.renderObject<RenderParagraph>(find.text(_tab1Text));
expect(textRenderObject.text.style.color, equals(labelColor));
final RenderParagraph iconRenderObject = _iconRenderObject(tester, Icons.looks_one);
expect(iconRenderObject.text.style.color, equals(labelColor));
});
testWidgets('Tab bar theme overrides label color (unselected)', (WidgetTester tester) async {
const Color unselectedLabelColor = Colors.black;
const TabBarTheme tabBarTheme = TabBarTheme(unselectedLabelColor: unselectedLabelColor);
await tester.pumpWidget(_withTheme(tabBarTheme));
final RenderParagraph textRenderObject = tester.renderObject<RenderParagraph>(find.text(_tab2Text));
expect(textRenderObject.text.style.color, equals(unselectedLabelColor));
final RenderParagraph iconRenderObject = _iconRenderObject(tester, Icons.looks_two);
expect(iconRenderObject.text.style.color, equals(unselectedLabelColor));
});
testWidgets('Tab bar theme overrides tab indicator size (tab)', (WidgetTester tester) async {
const TabBarTheme tabBarTheme = TabBarTheme(indicatorSize: TabBarIndicatorSize.tab);
await tester.pumpWidget(_withTheme(tabBarTheme));
await expectLater(
find.byKey(_painterKey),
matchesGoldenFile('tab_bar_theme.tab_indicator_size_tab.png'),
skip: !Platform.isLinux,
);
});
testWidgets('Tab bar theme overrides tab indicator size (label)', (WidgetTester tester) async {
const TabBarTheme tabBarTheme = TabBarTheme(indicatorSize: TabBarIndicatorSize.label);
await tester.pumpWidget(_withTheme(tabBarTheme));
await expectLater(
find.byKey(_painterKey),
matchesGoldenFile('tab_bar_theme.tab_indicator_size_label.png'),
skip: !Platform.isLinux,
);
});
testWidgets('Tab bar theme - custom tab indicator', (WidgetTester tester) async {
final TabBarTheme tabBarTheme = TabBarTheme(
indicator: BoxDecoration(
border: Border.all(color: Colors.black),
shape: BoxShape.rectangle,
)
);
await tester.pumpWidget(_withTheme(tabBarTheme));
await expectLater(
find.byKey(_painterKey),
matchesGoldenFile('tab_bar_theme.custom_tab_indicator.png'),
skip: !Platform.isLinux,
);
});
testWidgets('Tab bar theme - beveled rect indicator', (WidgetTester tester) async {
final TabBarTheme tabBarTheme = TabBarTheme(
indicator: ShapeDecoration(
shape: BeveledRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
color: Colors.black
),
);
await tester.pumpWidget(_withTheme(tabBarTheme));
await expectLater(
find.byKey(_painterKey),
matchesGoldenFile('tab_bar_theme.beveled_rect_indicator.png'),
skip: !Platform.isLinux,
);
});
}
...@@ -11,7 +11,7 @@ import 'package:flutter_test/flutter_test.dart'; ...@@ -11,7 +11,7 @@ import 'package:flutter_test/flutter_test.dart';
void main() { void main() {
test('ThemeDataTween control test', () { test('ThemeDataTween control test', () {
final ThemeData light = ThemeData.light(); final ThemeData light = ThemeData.light();
final ThemeData dark = ThemeData.light(); final ThemeData dark = ThemeData.dark();
final ThemeDataTween tween = ThemeDataTween(begin: light, end: dark); final ThemeDataTween tween = ThemeDataTween(begin: light, end: dark);
expect(tween.lerp(0.25), equals(ThemeData.lerp(light, dark, 0.25))); expect(tween.lerp(0.25), equals(ThemeData.lerp(light, dark, 0.25)));
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment