Unverified Commit 2bd7f9ff authored by Shi-Hao Hong's avatar Shi-Hao Hong Committed by GitHub

Update ToggleButtons constraints default and add new constraints parameter (#39857)

* Add constraints property, updated default constraints for ToggleButtons to 48x48

* Add kMinInteractiveDimension constant to ToggleButtons
parent a7cfdbd3
...@@ -9,6 +9,7 @@ import 'package:flutter/rendering.dart'; ...@@ -9,6 +9,7 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'button.dart'; import 'button.dart';
import 'constants.dart';
import 'debug.dart'; import 'debug.dart';
import 'theme.dart'; import 'theme.dart';
import 'theme_data.dart'; import 'theme_data.dart';
...@@ -166,6 +167,7 @@ class ToggleButtons extends StatelessWidget { ...@@ -166,6 +167,7 @@ class ToggleButtons extends StatelessWidget {
@required this.isSelected, @required this.isSelected,
this.onPressed, this.onPressed,
this.textStyle, this.textStyle,
this.constraints,
this.color, this.color,
this.selectedColor, this.selectedColor,
this.disabledColor, this.disabledColor,
...@@ -223,6 +225,14 @@ class ToggleButtons extends StatelessWidget { ...@@ -223,6 +225,14 @@ class ToggleButtons extends StatelessWidget {
/// are active, selected, or disabled. /// are active, selected, or disabled.
final TextStyle textStyle; final TextStyle textStyle;
/// Defines the button's size.
///
/// Typically used to constrain the button's minimum size.
///
/// If this property is null, then
/// BoxConstraints(minWidth: 48.0, minHeight: 48.0) is be used.
final BoxConstraints constraints;
/// The color for descendant [Text] and [Icon] widgets if the button is /// The color for descendant [Text] and [Icon] widgets if the button is
/// enabled and not selected. /// enabled and not selected.
/// ///
...@@ -578,6 +588,7 @@ class ToggleButtons extends StatelessWidget { ...@@ -578,6 +588,7 @@ class ToggleButtons extends StatelessWidget {
return _ToggleButton( return _ToggleButton(
selected: isSelected[index], selected: isSelected[index],
textStyle: textStyle, textStyle: textStyle,
constraints: constraints,
color: color, color: color,
selectedColor: selectedColor, selectedColor: selectedColor,
disabledColor: disabledColor, disabledColor: disabledColor,
...@@ -645,6 +656,7 @@ class _ToggleButton extends StatelessWidget { ...@@ -645,6 +656,7 @@ class _ToggleButton extends StatelessWidget {
Key key, Key key,
this.selected = false, this.selected = false,
this.textStyle, this.textStyle,
this.constraints,
this.color, this.color,
this.selectedColor, this.selectedColor,
this.disabledColor, this.disabledColor,
...@@ -671,6 +683,11 @@ class _ToggleButton extends StatelessWidget { ...@@ -671,6 +683,11 @@ class _ToggleButton extends StatelessWidget {
/// The [TextStyle] to apply to any text that appears in this button. /// The [TextStyle] to apply to any text that appears in this button.
final TextStyle textStyle; final TextStyle textStyle;
/// Defines the button's size.
///
/// Typically used to constrain the button's minimum size.
final BoxConstraints constraints;
/// The color for [Text] and [Icon] widgets if the button is enabled. /// The color for [Text] and [Icon] widgets if the button is enabled.
/// ///
/// If [selected] is false and [onPressed] is not null, this color will be used. /// If [selected] is false and [onPressed] is not null, this color will be used.
...@@ -784,6 +801,7 @@ class _ToggleButton extends StatelessWidget { ...@@ -784,6 +801,7 @@ class _ToggleButton extends StatelessWidget {
} }
final TextStyle currentTextStyle = textStyle ?? toggleButtonsTheme.textStyle ?? theme.textTheme.body1; final TextStyle currentTextStyle = textStyle ?? toggleButtonsTheme.textStyle ?? theme.textTheme.body1;
final BoxConstraints currentConstraints = constraints ?? toggleButtonsTheme.constraints ?? const BoxConstraints(minWidth: kMinInteractiveDimension, minHeight: kMinInteractiveDimension);
final Widget result = ClipRRect( final Widget result = ClipRRect(
borderRadius: clipRadius, borderRadius: clipRadius,
...@@ -791,6 +809,7 @@ class _ToggleButton extends StatelessWidget { ...@@ -791,6 +809,7 @@ class _ToggleButton extends StatelessWidget {
textStyle: currentTextStyle.copyWith( textStyle: currentTextStyle.copyWith(
color: currentColor, color: currentColor,
), ),
constraints: currentConstraints,
elevation: 0.0, elevation: 0.0,
highlightElevation: 0.0, highlightElevation: 0.0,
fillColor: currentFillColor, fillColor: currentFillColor,
......
...@@ -29,6 +29,7 @@ class ToggleButtonsThemeData extends Diagnosticable { ...@@ -29,6 +29,7 @@ class ToggleButtonsThemeData extends Diagnosticable {
/// [ToggleButtons]. /// [ToggleButtons].
const ToggleButtonsThemeData({ const ToggleButtonsThemeData({
this.textStyle, this.textStyle,
this.constraints,
this.color, this.color,
this.selectedColor, this.selectedColor,
this.disabledColor, this.disabledColor,
...@@ -51,6 +52,11 @@ class ToggleButtonsThemeData extends Diagnosticable { ...@@ -51,6 +52,11 @@ class ToggleButtonsThemeData extends Diagnosticable {
/// are active, selected, or disabled. /// are active, selected, or disabled.
final TextStyle textStyle; final TextStyle textStyle;
/// Defines the button's size.
///
/// Typically used to constrain the button's minimum size.
final BoxConstraints constraints;
/// The color for descendant [Text] and [Icon] widgets if the toggle button /// The color for descendant [Text] and [Icon] widgets if the toggle button
/// is enabled. /// is enabled.
final Color color; final Color color;
...@@ -104,6 +110,7 @@ class ToggleButtonsThemeData extends Diagnosticable { ...@@ -104,6 +110,7 @@ class ToggleButtonsThemeData extends Diagnosticable {
/// new values. /// new values.
ToggleButtonsThemeData copyWith({ ToggleButtonsThemeData copyWith({
TextStyle textStyle, TextStyle textStyle,
BoxConstraints constraints,
Color color, Color color,
Color selectedColor, Color selectedColor,
Color disabledColor, Color disabledColor,
...@@ -120,6 +127,7 @@ class ToggleButtonsThemeData extends Diagnosticable { ...@@ -120,6 +127,7 @@ class ToggleButtonsThemeData extends Diagnosticable {
}) { }) {
return ToggleButtonsThemeData( return ToggleButtonsThemeData(
textStyle: textStyle ?? this.textStyle, textStyle: textStyle ?? this.textStyle,
constraints: constraints ?? this.constraints,
color: color ?? this.color, color: color ?? this.color,
selectedColor: selectedColor ?? this.selectedColor, selectedColor: selectedColor ?? this.selectedColor,
disabledColor: disabledColor ?? this.disabledColor, disabledColor: disabledColor ?? this.disabledColor,
...@@ -143,6 +151,7 @@ class ToggleButtonsThemeData extends Diagnosticable { ...@@ -143,6 +151,7 @@ class ToggleButtonsThemeData extends Diagnosticable {
return null; return null;
return ToggleButtonsThemeData( return ToggleButtonsThemeData(
textStyle: TextStyle.lerp(a?.textStyle, b?.textStyle, t), textStyle: TextStyle.lerp(a?.textStyle, b?.textStyle, t),
constraints: BoxConstraints.lerp(a?.constraints, b?.constraints, t),
color: Color.lerp(a?.color, b?.color, t), color: Color.lerp(a?.color, b?.color, t),
selectedColor: Color.lerp(a?.selectedColor, b?.selectedColor, t), selectedColor: Color.lerp(a?.selectedColor, b?.selectedColor, t),
disabledColor: Color.lerp(a?.disabledColor, b?.disabledColor, t), disabledColor: Color.lerp(a?.disabledColor, b?.disabledColor, t),
...@@ -163,6 +172,7 @@ class ToggleButtonsThemeData extends Diagnosticable { ...@@ -163,6 +172,7 @@ class ToggleButtonsThemeData extends Diagnosticable {
int get hashCode { int get hashCode {
return hashValues( return hashValues(
textStyle, textStyle,
constraints,
color, color,
selectedColor, selectedColor,
disabledColor, disabledColor,
...@@ -187,6 +197,7 @@ class ToggleButtonsThemeData extends Diagnosticable { ...@@ -187,6 +197,7 @@ class ToggleButtonsThemeData extends Diagnosticable {
return false; return false;
final ToggleButtonsThemeData typedOther = other; final ToggleButtonsThemeData typedOther = other;
return typedOther.textStyle == textStyle return typedOther.textStyle == textStyle
&& typedOther.constraints == constraints
&& typedOther.color == color && typedOther.color == color
&& typedOther.selectedColor == selectedColor && typedOther.selectedColor == selectedColor
&& typedOther.disabledColor == disabledColor && typedOther.disabledColor == disabledColor
...@@ -206,6 +217,7 @@ class ToggleButtonsThemeData extends Diagnosticable { ...@@ -206,6 +217,7 @@ class ToggleButtonsThemeData extends Diagnosticable {
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
textStyle?.debugFillProperties(properties, prefix: 'textStyle.'); textStyle?.debugFillProperties(properties, prefix: 'textStyle.');
properties.add(DiagnosticsProperty<BoxConstraints>('constraints', constraints, defaultValue: null));
properties.add(ColorProperty('color', color, defaultValue: null)); properties.add(ColorProperty('color', color, defaultValue: null));
properties.add(ColorProperty('selectedColor', selectedColor, defaultValue: null)); properties.add(ColorProperty('selectedColor', selectedColor, defaultValue: null));
properties.add(ColorProperty('disabledColor', disabledColor, defaultValue: null)); properties.add(ColorProperty('disabledColor', disabledColor, defaultValue: null));
......
...@@ -309,6 +309,98 @@ void main() { ...@@ -309,6 +309,98 @@ void main() {
expect(textStyle.color, isNot(Colors.orange)); expect(textStyle.color, isNot(Colors.orange));
}); });
testWidgets('Default BoxConstraints', (WidgetTester tester) async {
await tester.pumpWidget(
Material(
child: boilerplate(
child: ToggleButtons(
isSelected: const <bool>[false, false, false],
onPressed: (int index) {},
children: const <Widget>[
Icon(Icons.check),
Icon(Icons.access_alarm),
Icon(Icons.cake),
],
),
),
),
);
final Rect firstRect = tester.getRect(find.byType(RawMaterialButton).at(0));
expect(firstRect.width, 48.0);
expect(firstRect.height, 48.0);
final Rect secondRect = tester.getRect(find.byType(RawMaterialButton).at(1));
expect(secondRect.width, 48.0);
expect(secondRect.height, 48.0);
final Rect thirdRect = tester.getRect(find.byType(RawMaterialButton).at(2));
expect(thirdRect.width, 48.0);
expect(thirdRect.height, 48.0);
});
testWidgets('Custom BoxConstraints', (WidgetTester tester) async {
// Test for minimum constraints
await tester.pumpWidget(
Material(
child: boilerplate(
child: ToggleButtons(
constraints: const BoxConstraints(
minWidth: 50.0,
minHeight: 60.0,
),
isSelected: const <bool>[false, false, false],
onPressed: (int index) {},
children: const <Widget>[
Icon(Icons.check),
Icon(Icons.access_alarm),
Icon(Icons.cake),
],
),
),
),
);
Rect firstRect = tester.getRect(find.byType(RawMaterialButton).at(0));
expect(firstRect.width, 50.0);
expect(firstRect.height, 60.0);
Rect secondRect = tester.getRect(find.byType(RawMaterialButton).at(1));
expect(secondRect.width, 50.0);
expect(secondRect.height, 60.0);
Rect thirdRect = tester.getRect(find.byType(RawMaterialButton).at(2));
expect(thirdRect.width, 50.0);
expect(thirdRect.height, 60.0);
// Test for maximum constraints
await tester.pumpWidget(
Material(
child: boilerplate(
child: ToggleButtons(
constraints: const BoxConstraints(
maxWidth: 20.0,
maxHeight: 10.0,
),
isSelected: const <bool>[false, false, false],
onPressed: (int index) {},
children: const <Widget>[
Icon(Icons.check),
Icon(Icons.access_alarm),
Icon(Icons.cake),
],
),
),
),
);
firstRect = tester.getRect(find.byType(RawMaterialButton).at(0));
expect(firstRect.width, 20.0);
expect(firstRect.height, 10.0);
secondRect = tester.getRect(find.byType(RawMaterialButton).at(1));
expect(secondRect.width, 20.0);
expect(secondRect.height, 10.0);
thirdRect = tester.getRect(find.byType(RawMaterialButton).at(2));
expect(thirdRect.width, 20.0);
expect(thirdRect.height, 10.0);
});
testWidgets( testWidgets(
'Default text/icon colors for enabled, selected and disabled states', 'Default text/icon colors for enabled, selected and disabled states',
(WidgetTester tester) async { (WidgetTester tester) async {
......
...@@ -25,6 +25,7 @@ void main() { ...@@ -25,6 +25,7 @@ void main() {
test('ToggleButtonsThemeData defaults', () { test('ToggleButtonsThemeData defaults', () {
const ToggleButtonsThemeData themeData = ToggleButtonsThemeData(); const ToggleButtonsThemeData themeData = ToggleButtonsThemeData();
expect(themeData.textStyle, null); expect(themeData.textStyle, null);
expect(themeData.constraints, null);
expect(themeData.color, null); expect(themeData.color, null);
expect(themeData.selectedColor, null); expect(themeData.selectedColor, null);
expect(themeData.disabledColor, null); expect(themeData.disabledColor, null);
...@@ -41,6 +42,7 @@ void main() { ...@@ -41,6 +42,7 @@ void main() {
const ToggleButtonsTheme theme = ToggleButtonsTheme(data: ToggleButtonsThemeData()); const ToggleButtonsTheme theme = ToggleButtonsTheme(data: ToggleButtonsThemeData());
expect(theme.data.textStyle, null); expect(theme.data.textStyle, null);
expect(theme.data.constraints, null);
expect(theme.data.color, null); expect(theme.data.color, null);
expect(theme.data.selectedColor, null); expect(theme.data.selectedColor, null);
expect(theme.data.disabledColor, null); expect(theme.data.disabledColor, null);
...@@ -72,6 +74,7 @@ void main() { ...@@ -72,6 +74,7 @@ void main() {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
const ToggleButtonsThemeData( const ToggleButtonsThemeData(
textStyle: TextStyle(fontSize: 10), textStyle: TextStyle(fontSize: 10),
constraints: BoxConstraints(minHeight: 10.0, maxHeight: 20.0),
color: Color(0xfffffff0), color: Color(0xfffffff0),
selectedColor: Color(0xfffffff1), selectedColor: Color(0xfffffff1),
disabledColor: Color(0xfffffff2), disabledColor: Color(0xfffffff2),
...@@ -95,6 +98,7 @@ void main() { ...@@ -95,6 +98,7 @@ void main() {
expect(description, <String>[ expect(description, <String>[
'textStyle.inherit: true', 'textStyle.inherit: true',
'textStyle.size: 10.0', 'textStyle.size: 10.0',
'constraints: BoxConstraints(0.0<=w<=Infinity, 10.0<=h<=20.0)',
'color: Color(0xfffffff0)', 'color: Color(0xfffffff0)',
'selectedColor: Color(0xfffffff1)', 'selectedColor: Color(0xfffffff1)',
'disabledColor: Color(0xfffffff2)', 'disabledColor: Color(0xfffffff2)',
...@@ -154,6 +158,78 @@ void main() { ...@@ -154,6 +158,78 @@ void main() {
expect(textStyle.color, isNot(Colors.orange)); expect(textStyle.color, isNot(Colors.orange));
}); });
testWidgets('Custom BoxConstraints', (WidgetTester tester) async {
// Test for minimum constraints
await tester.pumpWidget(
Material(
child: boilerplate(
child: ToggleButtonsTheme(
data: const ToggleButtonsThemeData(
constraints: BoxConstraints(
minWidth: 50.0,
minHeight: 60.0,
),
),
child: ToggleButtons(
isSelected: const <bool>[false, false, false],
onPressed: (int index) {},
children: const <Widget>[
Icon(Icons.check),
Icon(Icons.access_alarm),
Icon(Icons.cake),
],
),
),
),
),
);
Rect firstRect = tester.getRect(find.byType(RawMaterialButton).at(0));
expect(firstRect.width, 50.0);
expect(firstRect.height, 60.0);
Rect secondRect = tester.getRect(find.byType(RawMaterialButton).at(1));
expect(secondRect.width, 50.0);
expect(secondRect.height, 60.0);
Rect thirdRect = tester.getRect(find.byType(RawMaterialButton).at(2));
expect(thirdRect.width, 50.0);
expect(thirdRect.height, 60.0);
// Test for maximum constraints
await tester.pumpWidget(
Material(
child: boilerplate(
child: ToggleButtonsTheme(
data: const ToggleButtonsThemeData(
constraints: BoxConstraints(
maxWidth: 20.0,
maxHeight: 10.0,
),
),
child: ToggleButtons(
isSelected: const <bool>[false, false, false],
onPressed: (int index) {},
children: const <Widget>[
Icon(Icons.check),
Icon(Icons.access_alarm),
Icon(Icons.cake),
],
),
),
),
),
);
firstRect = tester.getRect(find.byType(RawMaterialButton).at(0));
expect(firstRect.width, 20.0);
expect(firstRect.height, 10.0);
secondRect = tester.getRect(find.byType(RawMaterialButton).at(1));
expect(secondRect.width, 20.0);
expect(secondRect.height, 10.0);
thirdRect = tester.getRect(find.byType(RawMaterialButton).at(2));
expect(thirdRect.width, 20.0);
expect(thirdRect.height, 10.0);
});
testWidgets( testWidgets(
'Theme text/icon colors for enabled, selected and disabled states', 'Theme text/icon colors for enabled, selected and disabled states',
(WidgetTester tester) async { (WidgetTester tester) async {
......
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