mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Material] ToggleButtons (#34599)
* Introduces ToggleButtons widget * Introduces ToggleButtonsTheme inherited widget * Introduces ThemeData.toggleButtonsTheme property
This commit is contained in:
parent
f1e87c48ef
commit
2e43b47008
@ -114,6 +114,8 @@ export 'src/material/theme.dart';
|
||||
export 'src/material/theme_data.dart';
|
||||
export 'src/material/time.dart';
|
||||
export 'src/material/time_picker.dart';
|
||||
export 'src/material/toggle_buttons.dart';
|
||||
export 'src/material/toggle_buttons_theme.dart';
|
||||
export 'src/material/toggleable.dart';
|
||||
export 'src/material/tooltip.dart';
|
||||
export 'src/material/tooltip_theme.dart';
|
||||
|
||||
@ -27,6 +27,7 @@ import 'slider_theme.dart';
|
||||
import 'snack_bar_theme.dart';
|
||||
import 'tab_bar_theme.dart';
|
||||
import 'text_theme.dart';
|
||||
import 'toggle_buttons_theme.dart';
|
||||
import 'tooltip_theme.dart';
|
||||
import 'typography.dart';
|
||||
|
||||
@ -136,6 +137,7 @@ class ThemeData extends Diagnosticable {
|
||||
Color disabledColor,
|
||||
Color buttonColor,
|
||||
ButtonThemeData buttonTheme,
|
||||
ToggleButtonsThemeData toggleButtonsTheme,
|
||||
Color secondaryHeaderColor,
|
||||
Color textSelectionColor,
|
||||
Color cursorColor,
|
||||
@ -253,6 +255,7 @@ class ThemeData extends Diagnosticable {
|
||||
splashColor: splashColor,
|
||||
materialTapTargetSize: materialTapTargetSize,
|
||||
);
|
||||
toggleButtonsTheme ??= const ToggleButtonsThemeData();
|
||||
disabledColor ??= isDark ? Colors.white38 : Colors.black38;
|
||||
highlightColor ??= isDark ? _kDarkThemeHighlightColor : _kLightThemeHighlightColor;
|
||||
splashColor ??= isDark ? _kDarkThemeSplashColor : _kLightThemeSplashColor;
|
||||
@ -297,6 +300,7 @@ class ThemeData extends Diagnosticable {
|
||||
disabledColor: disabledColor,
|
||||
buttonTheme: buttonTheme,
|
||||
buttonColor: buttonColor,
|
||||
toggleButtonsTheme: toggleButtonsTheme,
|
||||
toggleableActiveColor: toggleableActiveColor,
|
||||
secondaryHeaderColor: secondaryHeaderColor,
|
||||
textSelectionColor: textSelectionColor,
|
||||
@ -368,6 +372,7 @@ class ThemeData extends Diagnosticable {
|
||||
@required this.disabledColor,
|
||||
@required this.buttonTheme,
|
||||
@required this.buttonColor,
|
||||
@required this.toggleButtonsTheme,
|
||||
@required this.secondaryHeaderColor,
|
||||
@required this.textSelectionColor,
|
||||
@required this.cursorColor,
|
||||
@ -425,6 +430,7 @@ class ThemeData extends Diagnosticable {
|
||||
assert(disabledColor != null),
|
||||
assert(toggleableActiveColor != null),
|
||||
assert(buttonTheme != null),
|
||||
assert(toggleButtonsTheme != null),
|
||||
assert(secondaryHeaderColor != null),
|
||||
assert(textSelectionColor != null),
|
||||
assert(cursorColor != null),
|
||||
@ -593,6 +599,9 @@ class ThemeData extends Diagnosticable {
|
||||
/// and [FlatButton].
|
||||
final ButtonThemeData buttonTheme;
|
||||
|
||||
/// Defines the default configuration of [ToggleButtons] widgets.
|
||||
final ToggleButtonsThemeData toggleButtonsTheme;
|
||||
|
||||
/// The default fill color of the [Material] used in [RaisedButton]s.
|
||||
final Color buttonColor;
|
||||
|
||||
@ -802,6 +811,7 @@ class ThemeData extends Diagnosticable {
|
||||
Color unselectedWidgetColor,
|
||||
Color disabledColor,
|
||||
ButtonThemeData buttonTheme,
|
||||
ToggleButtonsTheme toggleButtonsTheme,
|
||||
Color buttonColor,
|
||||
Color secondaryHeaderColor,
|
||||
Color textSelectionColor,
|
||||
@ -863,6 +873,7 @@ class ThemeData extends Diagnosticable {
|
||||
disabledColor: disabledColor ?? this.disabledColor,
|
||||
buttonColor: buttonColor ?? this.buttonColor,
|
||||
buttonTheme: buttonTheme ?? this.buttonTheme,
|
||||
toggleButtonsTheme: toggleButtonsTheme ?? this.toggleButtonsTheme,
|
||||
secondaryHeaderColor: secondaryHeaderColor ?? this.secondaryHeaderColor,
|
||||
textSelectionColor: textSelectionColor ?? this.textSelectionColor,
|
||||
cursorColor: cursorColor ?? this.cursorColor,
|
||||
@ -1000,6 +1011,7 @@ class ThemeData extends Diagnosticable {
|
||||
unselectedWidgetColor: Color.lerp(a.unselectedWidgetColor, b.unselectedWidgetColor, t),
|
||||
disabledColor: Color.lerp(a.disabledColor, b.disabledColor, t),
|
||||
buttonTheme: t < 0.5 ? a.buttonTheme : b.buttonTheme,
|
||||
toggleButtonsTheme: ToggleButtonsThemeData.lerp(a.toggleButtonsTheme, b.toggleButtonsTheme, t),
|
||||
buttonColor: Color.lerp(a.buttonColor, b.buttonColor, t),
|
||||
secondaryHeaderColor: Color.lerp(a.secondaryHeaderColor, b.secondaryHeaderColor, t),
|
||||
textSelectionColor: Color.lerp(a.textSelectionColor, b.textSelectionColor, t),
|
||||
@ -1067,6 +1079,7 @@ class ThemeData extends Diagnosticable {
|
||||
(otherData.disabledColor == disabledColor) &&
|
||||
(otherData.buttonTheme == buttonTheme) &&
|
||||
(otherData.buttonColor == buttonColor) &&
|
||||
(otherData.toggleButtonsTheme == toggleButtonsTheme) &&
|
||||
(otherData.secondaryHeaderColor == secondaryHeaderColor) &&
|
||||
(otherData.textSelectionColor == textSelectionColor) &&
|
||||
(otherData.cursorColor == cursorColor) &&
|
||||
@ -1132,6 +1145,7 @@ class ThemeData extends Diagnosticable {
|
||||
disabledColor,
|
||||
buttonTheme,
|
||||
buttonColor,
|
||||
toggleButtonsTheme,
|
||||
toggleableActiveColor,
|
||||
secondaryHeaderColor,
|
||||
textSelectionColor,
|
||||
@ -1205,6 +1219,7 @@ class ThemeData extends Diagnosticable {
|
||||
properties.add(ColorProperty('errorColor', errorColor, defaultValue: defaultData.errorColor));
|
||||
properties.add(ColorProperty('toggleableActiveColor', toggleableActiveColor, defaultValue: defaultData.toggleableActiveColor));
|
||||
properties.add(DiagnosticsProperty<ButtonThemeData>('buttonTheme', buttonTheme));
|
||||
properties.add(DiagnosticsProperty<ToggleButtonsThemeData>('toggleButtonsTheme', toggleButtonsTheme));
|
||||
properties.add(DiagnosticsProperty<TextTheme>('textTheme', textTheme));
|
||||
properties.add(DiagnosticsProperty<TextTheme>('primaryTextTheme', primaryTextTheme));
|
||||
properties.add(DiagnosticsProperty<TextTheme>('accentTextTheme', accentTextTheme));
|
||||
|
||||
1190
packages/flutter/lib/src/material/toggle_buttons.dart
Normal file
1190
packages/flutter/lib/src/material/toggle_buttons.dart
Normal file
File diff suppressed because it is too large
Load Diff
272
packages/flutter/lib/src/material/toggle_buttons_theme.dart
Normal file
272
packages/flutter/lib/src/material/toggle_buttons_theme.dart
Normal file
@ -0,0 +1,272 @@
|
||||
// Copyright 2019 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:ui' show lerpDouble;
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import 'theme.dart';
|
||||
|
||||
/// Defines the color and border properties of [ToggleButtons] widgets.
|
||||
///
|
||||
/// Used by [ToggleButtonsTheme] to control the color and border properties
|
||||
/// of toggle buttons in a widget subtree.
|
||||
///
|
||||
/// To obtain the current [ToggleButtonsTheme], use [ToggleButtonsTheme.of].
|
||||
///
|
||||
/// Values specified here are used for [ToggleButtons] properties that are not
|
||||
/// given an explicit non-null value.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [ToggleButtonsTheme], which describes the actual configuration of a
|
||||
/// toggle buttons theme.
|
||||
class ToggleButtonsThemeData extends Diagnosticable {
|
||||
/// Creates the set of color and border properties used to configure
|
||||
/// [ToggleButtons].
|
||||
const ToggleButtonsThemeData({
|
||||
this.color,
|
||||
this.selectedColor,
|
||||
this.disabledColor,
|
||||
this.fillColor,
|
||||
this.focusColor,
|
||||
this.highlightColor,
|
||||
this.hoverColor,
|
||||
this.splashColor,
|
||||
this.borderColor,
|
||||
this.selectedBorderColor,
|
||||
this.disabledBorderColor,
|
||||
this.borderRadius,
|
||||
this.borderWidth,
|
||||
});
|
||||
|
||||
/// The color for descendant [Text] and [Icon] widgets if the toggle button
|
||||
/// is enabled.
|
||||
final Color color;
|
||||
|
||||
/// The color for descendant [Text] and [Icon] widgets if the toggle button
|
||||
/// is selected.
|
||||
final Color selectedColor;
|
||||
|
||||
/// The color for descendant [Text] and [Icon] widgets if the toggle button
|
||||
/// is disabled.
|
||||
final Color disabledColor;
|
||||
|
||||
/// The fill color for selected toggle buttons.
|
||||
final Color fillColor;
|
||||
|
||||
/// The color to use for filling the button when the button has input focus.
|
||||
final Color focusColor;
|
||||
|
||||
/// The highlight color for the toggle button's [InkWell].
|
||||
final Color highlightColor;
|
||||
|
||||
/// The splash color for the toggle button's [InkWell].
|
||||
final Color splashColor;
|
||||
|
||||
/// The color to use for filling the toggle button when the button has a
|
||||
/// pointer hovering over it.
|
||||
final Color hoverColor;
|
||||
|
||||
/// The border color to display when the toggle button is enabled.
|
||||
final Color borderColor;
|
||||
|
||||
/// The border color to display when the toggle button is selected.
|
||||
final Color selectedBorderColor;
|
||||
|
||||
/// The border color to display when the toggle button is disabled.
|
||||
final Color disabledBorderColor;
|
||||
|
||||
/// The width of the border surrounding each toggle button.
|
||||
///
|
||||
/// This applies to both the greater surrounding border, as well as the
|
||||
/// borders dividing each toggle button.
|
||||
///
|
||||
/// To render a hairline border (one physical pixel), set borderWidth to 0.0.
|
||||
/// See [BorderSide.width] for more details on hairline borders.
|
||||
final double borderWidth;
|
||||
|
||||
/// The radii of the border's corners.
|
||||
final BorderRadius borderRadius;
|
||||
|
||||
/// Creates a copy of this object but with the given fields replaced with the
|
||||
/// new values.
|
||||
ToggleButtonsThemeData copyWith({
|
||||
Color color,
|
||||
Color selectedColor,
|
||||
Color disabledColor,
|
||||
Color fillColor,
|
||||
Color focusColor,
|
||||
Color highlightColor,
|
||||
Color hoverColor,
|
||||
Color splashColor,
|
||||
Color borderColor,
|
||||
Color selectedBorderColor,
|
||||
Color disabledBorderColor,
|
||||
BorderRadius borderRadius,
|
||||
double borderWidth,
|
||||
}) {
|
||||
return ToggleButtonsThemeData(
|
||||
color: color ?? this.color,
|
||||
selectedColor: selectedColor ?? this.selectedColor,
|
||||
disabledColor: disabledColor ?? this.disabledColor,
|
||||
fillColor: fillColor ?? this.fillColor,
|
||||
focusColor: focusColor ?? this.focusColor,
|
||||
highlightColor: highlightColor ?? this.highlightColor,
|
||||
hoverColor: hoverColor ?? this.hoverColor,
|
||||
splashColor: splashColor ?? this.splashColor,
|
||||
borderColor: borderColor ?? this.borderColor,
|
||||
selectedBorderColor: selectedBorderColor ?? this.selectedBorderColor,
|
||||
disabledBorderColor: disabledBorderColor ?? this.disabledBorderColor,
|
||||
borderRadius: borderRadius ?? this.borderRadius,
|
||||
borderWidth: borderWidth ?? this.borderWidth,
|
||||
);
|
||||
}
|
||||
|
||||
/// Linearly interpolate between two toggle buttons themes.
|
||||
static ToggleButtonsThemeData lerp(ToggleButtonsThemeData a, ToggleButtonsThemeData b, double t) {
|
||||
assert (t != null);
|
||||
if (a == null && b == null)
|
||||
return null;
|
||||
return ToggleButtonsThemeData(
|
||||
color: Color.lerp(a?.color, b?.color, t),
|
||||
selectedColor: Color.lerp(a?.selectedColor, b?.selectedColor, t),
|
||||
disabledColor: Color.lerp(a?.disabledColor, b?.disabledColor, t),
|
||||
fillColor: Color.lerp(a?.fillColor, b?.fillColor, t),
|
||||
focusColor: Color.lerp(a?.focusColor, b?.focusColor, t),
|
||||
highlightColor: Color.lerp(a?.highlightColor, b?.highlightColor, t),
|
||||
hoverColor: Color.lerp(a?.hoverColor, b?.hoverColor, t),
|
||||
splashColor: Color.lerp(a?.splashColor, b?.splashColor, t),
|
||||
borderColor: Color.lerp(a?.borderColor, b?.borderColor, t),
|
||||
selectedBorderColor: Color.lerp(a?.selectedBorderColor, b?.selectedBorderColor, t),
|
||||
disabledBorderColor: Color.lerp(a?.disabledBorderColor, b?.disabledBorderColor, t),
|
||||
borderRadius: BorderRadius.lerp(a?.borderRadius, b?.borderRadius, t),
|
||||
borderWidth: lerpDouble(a?.borderWidth, b?.borderWidth, t),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return hashValues(
|
||||
color,
|
||||
selectedColor,
|
||||
disabledColor,
|
||||
fillColor,
|
||||
focusColor,
|
||||
highlightColor,
|
||||
hoverColor,
|
||||
splashColor,
|
||||
borderColor,
|
||||
selectedBorderColor,
|
||||
disabledBorderColor,
|
||||
borderRadius,
|
||||
borderWidth,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other))
|
||||
return true;
|
||||
if (other.runtimeType != runtimeType)
|
||||
return false;
|
||||
final ToggleButtonsThemeData typedOther = other;
|
||||
return typedOther.color == color
|
||||
&& typedOther.selectedColor == selectedColor
|
||||
&& typedOther.disabledColor == disabledColor
|
||||
&& typedOther.fillColor == fillColor
|
||||
&& typedOther.focusColor == focusColor
|
||||
&& typedOther.highlightColor == highlightColor
|
||||
&& typedOther.hoverColor == hoverColor
|
||||
&& typedOther.splashColor == splashColor
|
||||
&& typedOther.borderColor == borderColor
|
||||
&& typedOther.selectedBorderColor == selectedBorderColor
|
||||
&& typedOther.disabledBorderColor == disabledBorderColor
|
||||
&& typedOther.borderRadius == borderRadius
|
||||
&& typedOther.borderWidth == borderWidth;
|
||||
}
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
properties.add(ColorProperty('color', color, defaultValue: null));
|
||||
properties.add(ColorProperty('selectedColor', selectedColor, defaultValue: null));
|
||||
properties.add(ColorProperty('disabledColor', disabledColor, defaultValue: null));
|
||||
properties.add(ColorProperty('fillColor', fillColor, defaultValue: null));
|
||||
properties.add(ColorProperty('focusColor', focusColor, defaultValue: null));
|
||||
properties.add(ColorProperty('highlightColor', highlightColor, defaultValue: null));
|
||||
properties.add(ColorProperty('hoverColor', hoverColor, defaultValue: null));
|
||||
properties.add(ColorProperty('splashColor', splashColor, defaultValue: null));
|
||||
properties.add(ColorProperty('borderColor', borderColor, defaultValue: null));
|
||||
properties.add(ColorProperty('selectedBorderColor', selectedBorderColor, defaultValue: null));
|
||||
properties.add(ColorProperty('disabledBorderColor', disabledBorderColor, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<BorderRadius>('borderRadius', borderRadius, defaultValue: null));
|
||||
properties.add(DoubleProperty('borderWidth', borderWidth, defaultValue: null));
|
||||
}
|
||||
}
|
||||
|
||||
/// An inherited widget that defines color and border parameters for
|
||||
/// [ToggleButtons] in this widget's subtree.
|
||||
///
|
||||
/// Values specified here are used for [ToggleButtons] properties that are not
|
||||
/// given an explicit non-null value.
|
||||
class ToggleButtonsTheme extends InheritedWidget {
|
||||
/// Creates a toggle buttons theme that controls the color and border
|
||||
/// parameters for [ToggleButtons].
|
||||
ToggleButtonsTheme({
|
||||
Key key,
|
||||
Color color,
|
||||
Color selectedColor,
|
||||
Color disabledColor,
|
||||
Color fillColor,
|
||||
Color focusColor,
|
||||
Color highlightColor,
|
||||
Color hoverColor,
|
||||
Color splashColor,
|
||||
Color borderColor,
|
||||
Color selectedBorderColor,
|
||||
Color disabledBorderColor,
|
||||
BorderRadius borderRadius,
|
||||
double borderWidth,
|
||||
Widget child,
|
||||
}) : data = ToggleButtonsThemeData(
|
||||
color: color,
|
||||
selectedColor: selectedColor,
|
||||
disabledColor: disabledColor,
|
||||
fillColor: fillColor,
|
||||
focusColor: focusColor,
|
||||
highlightColor: highlightColor,
|
||||
hoverColor: hoverColor,
|
||||
splashColor: splashColor,
|
||||
borderColor: borderColor,
|
||||
selectedBorderColor: selectedBorderColor,
|
||||
disabledBorderColor: disabledBorderColor,
|
||||
borderRadius: borderRadius,
|
||||
borderWidth: borderWidth,
|
||||
),
|
||||
super(key: key, child: child);
|
||||
|
||||
/// Specifies the color and border values for descendant [ToggleButtons] widgets.
|
||||
final ToggleButtonsThemeData data;
|
||||
|
||||
/// The closest instance of this class that encloses the given context.
|
||||
///
|
||||
/// If there is no enclosing [ToggleButtonsTheme] widget, then
|
||||
/// [ThemeData.toggleButtonsTheme] is used.
|
||||
///
|
||||
/// Typical usage is as follows:
|
||||
///
|
||||
/// ```dart
|
||||
/// ToggleButtonsTheme theme = ToggleButtonsTheme.of(context);
|
||||
/// ```
|
||||
static ToggleButtonsThemeData of(BuildContext context) {
|
||||
final ToggleButtonsTheme toggleButtonsTheme = context.inheritFromWidgetOfExactType(ToggleButtonsTheme);
|
||||
return toggleButtonsTheme?.data ?? Theme.of(context).toggleButtonsTheme;
|
||||
}
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(ToggleButtonsTheme oldWidget) => data != oldWidget.data;
|
||||
}
|
||||
1306
packages/flutter/test/material/toggle_buttons_test.dart
Normal file
1306
packages/flutter/test/material/toggle_buttons_test.dart
Normal file
File diff suppressed because it is too large
Load Diff
446
packages/flutter/test/material/toggle_buttons_theme_test.dart
Normal file
446
packages/flutter/test/material/toggle_buttons_theme_test.dart
Normal file
@ -0,0 +1,446 @@
|
||||
// Copyright 2019 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/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../rendering/mock_canvas.dart';
|
||||
|
||||
Widget boilerplate({Widget child}) {
|
||||
return Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: Center(child: child),
|
||||
);
|
||||
}
|
||||
|
||||
void main() {
|
||||
test('ToggleButtonsThemeData copyWith, ==, hashCode basics', () {
|
||||
expect(const ToggleButtonsThemeData(), const ToggleButtonsThemeData().copyWith());
|
||||
expect(const ToggleButtonsThemeData().hashCode, const ToggleButtonsThemeData().copyWith().hashCode);
|
||||
});
|
||||
|
||||
test('ToggleButtonsThemeData defaults', () {
|
||||
const ToggleButtonsThemeData themeData = ToggleButtonsThemeData();
|
||||
expect(themeData.color, null);
|
||||
expect(themeData.selectedColor, null);
|
||||
expect(themeData.disabledColor, null);
|
||||
expect(themeData.fillColor, null);
|
||||
expect(themeData.focusColor, null);
|
||||
expect(themeData.highlightColor, null);
|
||||
expect(themeData.hoverColor, null);
|
||||
expect(themeData.splashColor, null);
|
||||
expect(themeData.borderColor, null);
|
||||
expect(themeData.selectedBorderColor, null);
|
||||
expect(themeData.disabledBorderColor, null);
|
||||
expect(themeData.borderRadius, null);
|
||||
expect(themeData.borderWidth, null);
|
||||
|
||||
final ToggleButtonsTheme theme = ToggleButtonsTheme();
|
||||
expect(theme.data.color, null);
|
||||
expect(theme.data.selectedColor, null);
|
||||
expect(theme.data.disabledColor, null);
|
||||
expect(theme.data.fillColor, null);
|
||||
expect(theme.data.focusColor, null);
|
||||
expect(theme.data.highlightColor, null);
|
||||
expect(theme.data.hoverColor, null);
|
||||
expect(theme.data.splashColor, null);
|
||||
expect(theme.data.borderColor, null);
|
||||
expect(theme.data.selectedBorderColor, null);
|
||||
expect(theme.data.disabledBorderColor, null);
|
||||
expect(theme.data.borderRadius, null);
|
||||
expect(theme.data.borderWidth, null);
|
||||
});
|
||||
|
||||
testWidgets('Default ToggleButtonsThemeData debugFillProperties', (WidgetTester tester) async {
|
||||
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
||||
const ToggleButtonsThemeData().debugFillProperties(builder);
|
||||
|
||||
final List<String> description = builder.properties
|
||||
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
|
||||
.map((DiagnosticsNode node) => node.toString())
|
||||
.toList();
|
||||
|
||||
expect(description, <String>[]);
|
||||
});
|
||||
|
||||
testWidgets('ToggleButtonsThemeData implements debugFillProperties', (WidgetTester tester) async {
|
||||
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
||||
const ToggleButtonsThemeData(
|
||||
color: Color(0xfffffff0),
|
||||
selectedColor: Color(0xfffffff1),
|
||||
disabledColor: Color(0xfffffff2),
|
||||
fillColor: Color(0xfffffff3),
|
||||
focusColor: Color(0xfffffff4),
|
||||
highlightColor: Color(0xfffffff5),
|
||||
hoverColor: Color(0xfffffff6),
|
||||
splashColor: Color(0xfffffff7),
|
||||
borderColor: Color(0xfffffff8),
|
||||
selectedBorderColor: Color(0xfffffff9),
|
||||
disabledBorderColor: Color(0xfffffffa),
|
||||
borderRadius: BorderRadius.all(Radius.circular(4.0)),
|
||||
borderWidth: 2.0,
|
||||
).debugFillProperties(builder);
|
||||
|
||||
final List<String> description = builder.properties
|
||||
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
|
||||
.map((DiagnosticsNode node) => node.toString())
|
||||
.toList();
|
||||
|
||||
expect(description, <String>[
|
||||
'color: Color(0xfffffff0)',
|
||||
'selectedColor: Color(0xfffffff1)',
|
||||
'disabledColor: Color(0xfffffff2)',
|
||||
'fillColor: Color(0xfffffff3)',
|
||||
'focusColor: Color(0xfffffff4)',
|
||||
'highlightColor: Color(0xfffffff5)',
|
||||
'hoverColor: Color(0xfffffff6)',
|
||||
'splashColor: Color(0xfffffff7)',
|
||||
'borderColor: Color(0xfffffff8)',
|
||||
'selectedBorderColor: Color(0xfffffff9)',
|
||||
'disabledBorderColor: Color(0xfffffffa)',
|
||||
'borderRadius: BorderRadius.circular(4.0)',
|
||||
'borderWidth: 2.0',
|
||||
]);
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'Theme text/icon colors for enabled, selected and disabled states',
|
||||
(WidgetTester tester) async {
|
||||
final ThemeData theme = ThemeData();
|
||||
const Color enabledColor = Colors.lime;
|
||||
const Color selectedColor = Colors.green;
|
||||
const Color disabledColor = Colors.yellow;
|
||||
|
||||
await tester.pumpWidget(
|
||||
Material(
|
||||
child: boilerplate(
|
||||
child: ToggleButtonsTheme(
|
||||
child: ToggleButtons(
|
||||
color: enabledColor,
|
||||
isSelected: const <bool>[false],
|
||||
onPressed: (int index) {},
|
||||
children: <Widget>[
|
||||
// This Row is used like this to test for both TextStyle
|
||||
// and IconTheme for Text and Icon widgets respectively.
|
||||
Row(children: const <Widget>[
|
||||
Text('First child'),
|
||||
Icon(Icons.check),
|
||||
]),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
DefaultTextStyle textStyle;
|
||||
IconTheme iconTheme;
|
||||
|
||||
// custom theme enabled color
|
||||
expect(theme.colorScheme.onSurface, isNot(enabledColor));
|
||||
textStyle = tester.firstWidget<DefaultTextStyle>(
|
||||
find.widgetWithText(DefaultTextStyle, 'First child'),
|
||||
);
|
||||
expect(textStyle.style.color, enabledColor);
|
||||
iconTheme = tester.firstWidget<IconTheme>(
|
||||
find.widgetWithIcon(IconTheme, Icons.check),
|
||||
);
|
||||
expect(iconTheme.data.color, enabledColor);
|
||||
|
||||
await tester.pumpWidget(
|
||||
Material(
|
||||
child: boilerplate(
|
||||
child: ToggleButtonsTheme(
|
||||
selectedColor: selectedColor,
|
||||
child: ToggleButtons(
|
||||
color: enabledColor,
|
||||
isSelected: const <bool>[true],
|
||||
onPressed: (int index) {},
|
||||
children: <Widget>[
|
||||
Row(children: const <Widget>[
|
||||
Text('First child'),
|
||||
Icon(Icons.check),
|
||||
]),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
// custom theme selected color
|
||||
expect(theme.colorScheme.primary, isNot(selectedColor));
|
||||
textStyle = tester.firstWidget<DefaultTextStyle>(
|
||||
find.widgetWithText(DefaultTextStyle, 'First child'),
|
||||
);
|
||||
expect(textStyle.style.color, selectedColor);
|
||||
iconTheme = tester.firstWidget<IconTheme>(
|
||||
find.widgetWithIcon(IconTheme, Icons.check),
|
||||
);
|
||||
expect(iconTheme.data.color, selectedColor);
|
||||
|
||||
await tester.pumpWidget(
|
||||
Material(
|
||||
child: boilerplate(
|
||||
child: ToggleButtonsTheme(
|
||||
disabledColor: disabledColor,
|
||||
child: ToggleButtons(
|
||||
color: enabledColor,
|
||||
isSelected: const <bool>[false],
|
||||
children: <Widget>[
|
||||
Row(children: const <Widget>[
|
||||
Text('First child'),
|
||||
Icon(Icons.check),
|
||||
]),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
// custom theme disabled color
|
||||
expect(theme.disabledColor, isNot(disabledColor));
|
||||
textStyle = tester.firstWidget<DefaultTextStyle>(
|
||||
find.widgetWithText(DefaultTextStyle, 'First child'),
|
||||
);
|
||||
expect(textStyle.style.color, disabledColor);
|
||||
iconTheme = tester.firstWidget<IconTheme>(
|
||||
find.widgetWithIcon(IconTheme, Icons.check),
|
||||
);
|
||||
expect(iconTheme.data.color, disabledColor);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets('Theme button fillColor', (WidgetTester tester) async {
|
||||
const Color customFillColor = Colors.green;
|
||||
await tester.pumpWidget(
|
||||
Material(
|
||||
child: boilerplate(
|
||||
child: ToggleButtonsTheme(
|
||||
fillColor: customFillColor,
|
||||
child: ToggleButtons(
|
||||
isSelected: const <bool>[true],
|
||||
onPressed: (int index) {},
|
||||
children: <Widget>[
|
||||
Row(children: const <Widget>[
|
||||
Text('First child'),
|
||||
]),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final Material material = tester.firstWidget<Material>(
|
||||
find.descendant(
|
||||
of: find.byType(RawMaterialButton),
|
||||
matching: find.byType(Material),
|
||||
),
|
||||
);
|
||||
expect(material.color, customFillColor);
|
||||
expect(material.type, MaterialType.button);
|
||||
});
|
||||
|
||||
testWidgets('Theme InkWell colors', (WidgetTester tester) async {
|
||||
const Color splashColor = Color(0xff4caf50);
|
||||
const Color highlightColor = Color(0xffcddc39);
|
||||
const Color hoverColor = Color(0xffffeb3b);
|
||||
const Color focusColor = Color(0xffffff00);
|
||||
final FocusNode focusNode = FocusNode();
|
||||
|
||||
await tester.pumpWidget(
|
||||
Material(
|
||||
child: boilerplate(
|
||||
child: ToggleButtonsTheme(
|
||||
splashColor: splashColor,
|
||||
highlightColor: highlightColor,
|
||||
hoverColor: hoverColor,
|
||||
focusColor: focusColor,
|
||||
child: ToggleButtons(
|
||||
isSelected: const <bool>[true],
|
||||
onPressed: (int index) {},
|
||||
focusNodes: <FocusNode>[focusNode],
|
||||
children: const <Widget>[
|
||||
Text('First child'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final Offset center = tester.getCenter(find.text('First child'));
|
||||
|
||||
// splashColor
|
||||
// highlightColor
|
||||
final TestGesture touchGesture = await tester.createGesture();
|
||||
await touchGesture.down(center);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
RenderObject inkFeatures;
|
||||
inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) {
|
||||
return object.runtimeType.toString() == '_RenderInkFeatures';
|
||||
});
|
||||
expect(
|
||||
inkFeatures,
|
||||
paints
|
||||
..circle(color: splashColor)
|
||||
..rect(color: highlightColor),
|
||||
);
|
||||
|
||||
await touchGesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// hoverColor
|
||||
final TestGesture hoverGesture = await tester.createGesture(
|
||||
kind: PointerDeviceKind.mouse,
|
||||
);
|
||||
await hoverGesture.addPointer();
|
||||
await hoverGesture.moveTo(center);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) {
|
||||
return object.runtimeType.toString() == '_RenderInkFeatures';
|
||||
});
|
||||
expect(inkFeatures, paints..rect(color: hoverColor));
|
||||
await hoverGesture.removePointer();
|
||||
|
||||
// focusColor
|
||||
focusNode.requestFocus();
|
||||
await tester.pumpAndSettle();
|
||||
inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) {
|
||||
return object.runtimeType.toString() == '_RenderInkFeatures';
|
||||
});
|
||||
expect(inkFeatures, paints..rect(color: focusColor));
|
||||
});
|
||||
|
||||
|
||||
testWidgets(
|
||||
'Theme border width and border colors for enabled, selected and disabled states',
|
||||
(WidgetTester tester) async {
|
||||
const Color borderColor = Color(0xff4caf50);
|
||||
const Color selectedBorderColor = Color(0xffcddc39);
|
||||
const Color disabledBorderColor = Color(0xffffeb3b);
|
||||
const double customWidth = 2.0;
|
||||
|
||||
await tester.pumpWidget(
|
||||
Material(
|
||||
child: boilerplate(
|
||||
child: ToggleButtonsTheme(
|
||||
borderColor: borderColor,
|
||||
borderWidth: customWidth,
|
||||
child: ToggleButtons(
|
||||
isSelected: const <bool>[false],
|
||||
onPressed: (int index) {},
|
||||
children: const <Widget>[
|
||||
Text('First child'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
RenderObject toggleButtonRenderObject;
|
||||
toggleButtonRenderObject = tester.allRenderObjects.firstWhere((RenderObject object) {
|
||||
return object.runtimeType.toString() == '_SelectToggleButtonRenderObject';
|
||||
});
|
||||
expect(
|
||||
toggleButtonRenderObject,
|
||||
paints
|
||||
// trailing side
|
||||
..path(
|
||||
style: PaintingStyle.stroke,
|
||||
color: borderColor,
|
||||
strokeWidth: customWidth,
|
||||
)
|
||||
// leading side, top and bottom
|
||||
..path(
|
||||
style: PaintingStyle.stroke,
|
||||
color: borderColor,
|
||||
strokeWidth: customWidth,
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
Material(
|
||||
child: boilerplate(
|
||||
child: ToggleButtonsTheme(
|
||||
selectedBorderColor: selectedBorderColor,
|
||||
borderWidth: customWidth,
|
||||
child: ToggleButtons(
|
||||
isSelected: const <bool>[true],
|
||||
onPressed: (int index) {},
|
||||
children: const <Widget>[
|
||||
Text('First child'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
toggleButtonRenderObject = tester.allRenderObjects.firstWhere((RenderObject object) {
|
||||
return object.runtimeType.toString() == '_SelectToggleButtonRenderObject';
|
||||
});
|
||||
expect(
|
||||
toggleButtonRenderObject,
|
||||
paints
|
||||
// trailing side
|
||||
..path(
|
||||
style: PaintingStyle.stroke,
|
||||
color: selectedBorderColor,
|
||||
strokeWidth: customWidth,
|
||||
)
|
||||
// leading side, top and bottom
|
||||
..path(
|
||||
style: PaintingStyle.stroke,
|
||||
color: selectedBorderColor,
|
||||
strokeWidth: customWidth,
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
Material(
|
||||
child: boilerplate(
|
||||
child: ToggleButtonsTheme(
|
||||
disabledBorderColor: disabledBorderColor,
|
||||
borderWidth: customWidth,
|
||||
child: ToggleButtons(
|
||||
isSelected: const <bool>[false],
|
||||
children: const <Widget>[
|
||||
Text('First child'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
toggleButtonRenderObject = tester.allRenderObjects.firstWhere((RenderObject object) {
|
||||
return object.runtimeType.toString() == '_SelectToggleButtonRenderObject';
|
||||
});
|
||||
expect(
|
||||
toggleButtonRenderObject,
|
||||
paints
|
||||
// trailing side
|
||||
..path(
|
||||
style: PaintingStyle.stroke,
|
||||
color: disabledBorderColor,
|
||||
strokeWidth: customWidth,
|
||||
)
|
||||
// leading side, top and bottom
|
||||
..path(
|
||||
style: PaintingStyle.stroke,
|
||||
color: disabledBorderColor,
|
||||
strokeWidth: customWidth,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user