Add SegmentedButton.styleFrom
(#137542)
fixes https://github.com/flutter/flutter/issues/138289 --- SegmentedButtom.styleFrom has been added to the segment button, so there is no longer any need to the button style from the beginning. It works like ElevatedButton.styleFrom only I added selectedForegroundColor, selectedBackgroundColor. In this way, the user will be able to change the color first without checking the MaterialState states. I added tests of the same controls. #129215 I opened this problem myself, but I was rejected because I handled too many items in a PR. For now, I wrote a structure that only handles MaterialStates instead of users. old (still avaliable) <img width="626" alt="image" src="https://github.com/flutter/flutter/assets/65075121/9446b13b-c355-4d20-bda2-c47a23d42d4f"> new (just an option for developer) <img width="483" alt="image" src="https://github.com/flutter/flutter/assets/65075121/0a645257-4c83-4029-9484-bd746c02265f"> ### Code sample <details> <summary>expand to view the code sample</summary> ```dart import 'package:flutter/material.dart'; /// Flutter code sample for [SegmentedButton]. void main() { runApp(const SegmentedButtonApp()); } enum Calendar { day, week, month, year } class SegmentedButtonApp extends StatefulWidget { const SegmentedButtonApp({super.key}); @override State<SegmentedButtonApp> createState() => _SegmentedButtonAppState(); } class _SegmentedButtonAppState extends State<SegmentedButtonApp> { Calendar calendarView = Calendar.day; @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(useMaterial3: true), home: Scaffold( body: Center( child: SegmentedButton<Calendar>( style: SegmentedButton.styleFrom( foregroundColor: Colors.amber, visualDensity: VisualDensity.comfortable, ), // style: const ButtonStyle( // foregroundColor: MaterialStatePropertyAll<Color>(Colors.deepPurple), // visualDensity: VisualDensity.comfortable, // ), segments: const <ButtonSegment<Calendar>>[ ButtonSegment<Calendar>( value: Calendar.day, label: Text('Day'), icon: Icon(Icons.calendar_view_day)), ButtonSegment<Calendar>( value: Calendar.week, label: Text('Week'), icon: Icon(Icons.calendar_view_week)), ButtonSegment<Calendar>( value: Calendar.month, label: Text('Month'), icon: Icon(Icons.calendar_view_month)), ButtonSegment<Calendar>( value: Calendar.year, label: Text('Year'), icon: Icon(Icons.calendar_today)), ], selected: <Calendar>{calendarView}, onSelectionChanged: (Set<Calendar> newSelection) { setState(() { calendarView = newSelection.first; }); }, ), ), ), ); } } ``` </details>
This commit is contained in:
parent
e64e7d9c13
commit
83ac76050d
@ -119,6 +119,33 @@ class _${blockName}DefaultsM3 extends SegmentedButtonThemeData {
|
||||
}
|
||||
@override
|
||||
Widget? get selectedIcon => const Icon(Icons.check);
|
||||
|
||||
static MaterialStateProperty<Color?> resolveStateColor(Color? unselectedColor, Color? selectedColor){
|
||||
return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.selected)) {
|
||||
if (states.contains(MaterialState.pressed)) {
|
||||
return selectedColor?.withOpacity(0.12);
|
||||
}
|
||||
if (states.contains(MaterialState.hovered)) {
|
||||
return selectedColor?.withOpacity(0.08);
|
||||
}
|
||||
if (states.contains(MaterialState.focused)) {
|
||||
return selectedColor?.withOpacity(0.12);
|
||||
}
|
||||
} else {
|
||||
if (states.contains(MaterialState.pressed)) {
|
||||
return unselectedColor?.withOpacity(0.12);
|
||||
}
|
||||
if (states.contains(MaterialState.hovered)) {
|
||||
return unselectedColor?.withOpacity(0.08);
|
||||
}
|
||||
if (states.contains(MaterialState.focused)) {
|
||||
return unselectedColor?.withOpacity(0.12);
|
||||
}
|
||||
}
|
||||
return Colors.transparent;
|
||||
});
|
||||
}
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
@ -0,0 +1,66 @@
|
||||
// Copyright 2014 The Flutter 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/material.dart';
|
||||
|
||||
/// Flutter code sample for [SegmentedButton.styleFrom].
|
||||
|
||||
void main() {
|
||||
runApp(const SegmentedButtonApp());
|
||||
}
|
||||
|
||||
class SegmentedButtonApp extends StatelessWidget {
|
||||
const SegmentedButtonApp({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: Center(
|
||||
child: SegmentedButtonExample(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SegmentedButtonExample extends StatefulWidget {
|
||||
const SegmentedButtonExample({super.key});
|
||||
|
||||
@override
|
||||
State<SegmentedButtonExample> createState() => _SegmentedButtonExampleState();
|
||||
}
|
||||
|
||||
enum Calendar { day, week, month, year }
|
||||
|
||||
class _SegmentedButtonExampleState extends State<SegmentedButtonExample> {
|
||||
Calendar calendarView = Calendar.week;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SegmentedButton<Calendar>(
|
||||
style: SegmentedButton.styleFrom(
|
||||
backgroundColor: Colors.grey[200],
|
||||
foregroundColor: Colors.red,
|
||||
selectedForegroundColor: Colors.white,
|
||||
selectedBackgroundColor: Colors.green,
|
||||
),
|
||||
segments: const <ButtonSegment<Calendar>>[
|
||||
ButtonSegment<Calendar>(value: Calendar.day, label: Text('Day'), icon: Icon(Icons.calendar_view_day)),
|
||||
ButtonSegment<Calendar>(value: Calendar.week, label: Text('Week'), icon: Icon(Icons.calendar_view_week)),
|
||||
ButtonSegment<Calendar>(value: Calendar.month, label: Text('Month'), icon: Icon(Icons.calendar_view_month)),
|
||||
ButtonSegment<Calendar>(value: Calendar.year, label: Text('Year'), icon: Icon(Icons.calendar_today)),
|
||||
],
|
||||
selected: <Calendar>{calendarView},
|
||||
onSelectionChanged: (Set<Calendar> newSelection) {
|
||||
setState(() {
|
||||
// By default there is only a single segment that can be
|
||||
// selected at one time, so its value is always the first
|
||||
// item in the selected set.
|
||||
calendarView = newSelection.first;
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
// Copyright 2014 The Flutter 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/material.dart';
|
||||
import 'package:flutter_api_samples/material/segmented_button/segmented_button.1.dart'
|
||||
as example;
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Can use SegmentedButton.styleFrom to customize SegmentedButton', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const example.SegmentedButtonApp(),
|
||||
);
|
||||
|
||||
final Color unselectedBackgroundColor = Colors.grey[200]!;
|
||||
const Color unselectedForegroundColor = Colors.red;
|
||||
const Color selectedBackgroundColor = Colors.green;
|
||||
const Color selectedForegroundColor = Colors.white;
|
||||
|
||||
Material getMaterial(String text) {
|
||||
return tester.widget<Material>(find.ancestor(
|
||||
of: find.text(text),
|
||||
matching: find.byType(Material),
|
||||
).first);
|
||||
}
|
||||
|
||||
// Verify the unselected button style.
|
||||
expect(getMaterial('Day').textStyle?.color, unselectedForegroundColor);
|
||||
expect(getMaterial('Day').color, unselectedBackgroundColor);
|
||||
|
||||
// Verify the selected button style.
|
||||
expect(getMaterial('Week').textStyle?.color, selectedForegroundColor);
|
||||
expect(getMaterial('Week').color, selectedBackgroundColor);
|
||||
});
|
||||
}
|
@ -8,15 +8,18 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'button_style.dart';
|
||||
import 'button_style_button.dart';
|
||||
import 'color_scheme.dart';
|
||||
import 'colors.dart';
|
||||
import 'icons.dart';
|
||||
import 'ink_well.dart';
|
||||
import 'material.dart';
|
||||
import 'material_state.dart';
|
||||
import 'segmented_button_theme.dart';
|
||||
import 'text_button.dart';
|
||||
import 'text_button_theme.dart';
|
||||
import 'theme.dart';
|
||||
import 'theme_data.dart';
|
||||
import 'tooltip.dart';
|
||||
|
||||
/// Data describing a segment of a [SegmentedButton].
|
||||
@ -86,6 +89,12 @@ class ButtonSegment<T> {
|
||||
/// ** See code in examples/api/lib/material/segmented_button/segmented_button.0.dart **
|
||||
/// {@end-tool}
|
||||
///
|
||||
/// {@tool dartpad}
|
||||
/// This sample showcases how to customize [SegmentedButton] using [SegmentedButton.styleFrom].
|
||||
///
|
||||
/// ** See code in examples/api/lib/material/segmented_button/segmented_button.1.dart **
|
||||
/// {@end-tool}
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * Material Design spec: <https://m3.material.io/components/segmented-buttons/overview>
|
||||
@ -178,6 +187,123 @@ class SegmentedButton<T> extends StatefulWidget {
|
||||
/// [onSelectionChanged] will not be called.
|
||||
final bool emptySelectionAllowed;
|
||||
|
||||
/// A static convenience method that constructs a segmented button
|
||||
/// [ButtonStyle] given simple values.
|
||||
///
|
||||
/// The [foregroundColor], [selectedForegroundColor], and [disabledForegroundColor]
|
||||
/// colors are used to create a [MaterialStateProperty] [ButtonStyle.foregroundColor],
|
||||
/// and a derived [ButtonStyle.overlayColor].
|
||||
///
|
||||
/// The [backgroundColor], [selectedBackgroundColor] and [disabledBackgroundColor]
|
||||
/// colors are used to create a [MaterialStateProperty] [ButtonStyle.backgroundColor].
|
||||
///
|
||||
/// Similarly, the [enabledMouseCursor] and [disabledMouseCursor]
|
||||
/// parameters are used to construct [ButtonStyle.mouseCursor].
|
||||
///
|
||||
/// All of the other parameters are either used directly or used to
|
||||
/// create a [MaterialStateProperty] with a single value for all
|
||||
/// states.
|
||||
///
|
||||
/// All parameters default to null. By default this method returns
|
||||
/// a [ButtonStyle] that doesn't override anything.
|
||||
///
|
||||
/// {@tool snippet}
|
||||
///
|
||||
/// For example, to override the default text and icon colors for a
|
||||
/// [SegmentedButton], as well as its overlay color, with all of the
|
||||
/// standard opacity adjustments for the pressed, focused, and
|
||||
/// hovered states, one could write:
|
||||
///
|
||||
/// ** See code in examples/api/lib/material/segmented_button/segmented_button.1.dart **
|
||||
///
|
||||
/// ```dart
|
||||
/// SegmentedButton<int>(
|
||||
/// style: SegmentedButton.styleFrom(
|
||||
/// foregroundColor: Colors.black,
|
||||
/// selectedForegroundColor: Colors.white,
|
||||
/// backgroundColor: Colors.amber,
|
||||
/// selectedBackgroundColor: Colors.red,
|
||||
/// ),
|
||||
/// segments: const <ButtonSegment<int>>[
|
||||
/// ButtonSegment<int>(
|
||||
/// value: 0,
|
||||
/// label: Text('0'),
|
||||
/// icon: Icon(Icons.calendar_view_day),
|
||||
/// ),
|
||||
/// ButtonSegment<int>(
|
||||
/// value: 1,
|
||||
/// label: Text('1'),
|
||||
/// icon: Icon(Icons.calendar_view_week),
|
||||
/// ),
|
||||
/// ],
|
||||
/// selected: const <int>{0},
|
||||
/// onSelectionChanged: (Set<int> selection) {},
|
||||
/// ),
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
static ButtonStyle styleFrom({
|
||||
Color? foregroundColor,
|
||||
Color? backgroundColor,
|
||||
Color? selectedForegroundColor,
|
||||
Color? selectedBackgroundColor,
|
||||
Color? disabledForegroundColor,
|
||||
Color? disabledBackgroundColor,
|
||||
Color? shadowColor,
|
||||
Color? surfaceTintColor,
|
||||
double? elevation,
|
||||
TextStyle? textStyle,
|
||||
EdgeInsetsGeometry? padding,
|
||||
Size? minimumSize,
|
||||
Size? fixedSize,
|
||||
Size? maximumSize,
|
||||
BorderSide? side,
|
||||
OutlinedBorder? shape,
|
||||
MouseCursor? enabledMouseCursor,
|
||||
MouseCursor? disabledMouseCursor,
|
||||
VisualDensity? visualDensity,
|
||||
MaterialTapTargetSize? tapTargetSize,
|
||||
Duration? animationDuration,
|
||||
bool? enableFeedback,
|
||||
AlignmentGeometry? alignment,
|
||||
InteractiveInkFeatureFactory? splashFactory,
|
||||
}) {
|
||||
final MaterialStateProperty<Color?>? foregroundColorProp =
|
||||
(foregroundColor == null && disabledForegroundColor == null && selectedForegroundColor == null)
|
||||
? null
|
||||
: _SegmentButtonDefaultColor(foregroundColor, disabledForegroundColor, selectedForegroundColor);
|
||||
final MaterialStateProperty<Color?>? backgroundColorProp =
|
||||
(backgroundColor == null && disabledBackgroundColor == null && selectedBackgroundColor == null)
|
||||
? null
|
||||
: _SegmentButtonDefaultColor(backgroundColor, disabledBackgroundColor, selectedBackgroundColor);
|
||||
final MaterialStateProperty<Color?>? overlayColor = (foregroundColor == null && selectedForegroundColor == null)
|
||||
? null
|
||||
: _SegmentedButtonDefaultsM3.resolveStateColor(foregroundColor, selectedForegroundColor);
|
||||
return TextButton.styleFrom(
|
||||
textStyle: textStyle,
|
||||
shadowColor: shadowColor,
|
||||
surfaceTintColor: surfaceTintColor,
|
||||
elevation: elevation,
|
||||
padding: padding,
|
||||
minimumSize: minimumSize,
|
||||
fixedSize: fixedSize,
|
||||
maximumSize: maximumSize,
|
||||
side: side,
|
||||
shape: shape,
|
||||
enabledMouseCursor: enabledMouseCursor,
|
||||
disabledMouseCursor: disabledMouseCursor,
|
||||
visualDensity: visualDensity,
|
||||
tapTargetSize: tapTargetSize,
|
||||
animationDuration: animationDuration,
|
||||
enableFeedback: enableFeedback,
|
||||
alignment: alignment,
|
||||
splashFactory: splashFactory,
|
||||
).copyWith(
|
||||
foregroundColor: foregroundColorProp,
|
||||
backgroundColor: backgroundColorProp,
|
||||
overlayColor: overlayColor,
|
||||
);
|
||||
}
|
||||
|
||||
/// Customizes this button's appearance.
|
||||
///
|
||||
/// The following style properties apply to the entire segmented button:
|
||||
@ -417,6 +543,27 @@ class SegmentedButtonState<T> extends State<SegmentedButton<T>> {
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@immutable
|
||||
class _SegmentButtonDefaultColor extends MaterialStateProperty<Color?> with Diagnosticable {
|
||||
_SegmentButtonDefaultColor(this.color, this.disabled, this.selected);
|
||||
|
||||
final Color? color;
|
||||
final Color? disabled;
|
||||
final Color? selected;
|
||||
|
||||
@override
|
||||
Color? resolve(Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.disabled)) {
|
||||
return disabled;
|
||||
}
|
||||
if (states.contains(MaterialState.selected)) {
|
||||
return selected;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
class _SegmentedButtonRenderWidget<T> extends MultiChildRenderObjectWidget {
|
||||
const _SegmentedButtonRenderWidget({
|
||||
super.key,
|
||||
@ -842,6 +989,33 @@ class _SegmentedButtonDefaultsM3 extends SegmentedButtonThemeData {
|
||||
}
|
||||
@override
|
||||
Widget? get selectedIcon => const Icon(Icons.check);
|
||||
|
||||
static MaterialStateProperty<Color?> resolveStateColor(Color? unselectedColor, Color? selectedColor){
|
||||
return MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.selected)) {
|
||||
if (states.contains(MaterialState.pressed)) {
|
||||
return selectedColor?.withOpacity(0.12);
|
||||
}
|
||||
if (states.contains(MaterialState.hovered)) {
|
||||
return selectedColor?.withOpacity(0.08);
|
||||
}
|
||||
if (states.contains(MaterialState.focused)) {
|
||||
return selectedColor?.withOpacity(0.12);
|
||||
}
|
||||
} else {
|
||||
if (states.contains(MaterialState.pressed)) {
|
||||
return unselectedColor?.withOpacity(0.12);
|
||||
}
|
||||
if (states.contains(MaterialState.hovered)) {
|
||||
return unselectedColor?.withOpacity(0.08);
|
||||
}
|
||||
if (states.contains(MaterialState.focused)) {
|
||||
return unselectedColor?.withOpacity(0.12);
|
||||
}
|
||||
}
|
||||
return Colors.transparent;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// END GENERATED TOKEN PROPERTIES - SegmentedButton
|
||||
|
@ -664,4 +664,118 @@ testWidgets('SegmentedButton shows checkboxes for selected segments', (WidgetTes
|
||||
expect(find.byTooltip('t2'), findsOneWidget);
|
||||
expect(find.byTooltip('t3'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('SegmentedButton.styleFrom is applied to the SegmentedButton', (WidgetTester tester) async {
|
||||
const Color foregroundColor = Color(0xfffffff0);
|
||||
const Color backgroundColor = Color(0xfffffff1);
|
||||
const Color selectedBackgroundColor = Color(0xfffffff2);
|
||||
const Color selectedForegroundColor = Color(0xfffffff3);
|
||||
const Color disabledBackgroundColor = Color(0xfffffff4);
|
||||
const Color disabledForegroundColor = Color(0xfffffff5);
|
||||
const MouseCursor enabledMouseCursor = SystemMouseCursors.text;
|
||||
const MouseCursor disabledMouseCursor = SystemMouseCursors.grab;
|
||||
|
||||
final ButtonStyle styleFromStyle = SegmentedButton.styleFrom(
|
||||
foregroundColor: foregroundColor,
|
||||
backgroundColor: backgroundColor,
|
||||
selectedForegroundColor: selectedForegroundColor,
|
||||
selectedBackgroundColor: selectedBackgroundColor,
|
||||
disabledForegroundColor: disabledForegroundColor,
|
||||
disabledBackgroundColor: disabledBackgroundColor,
|
||||
shadowColor: const Color(0xfffffff6),
|
||||
surfaceTintColor: const Color(0xfffffff7),
|
||||
elevation: 1,
|
||||
textStyle: const TextStyle(color: Color(0xfffffff8)),
|
||||
padding: const EdgeInsets.all(2),
|
||||
side: const BorderSide(color: Color(0xfffffff9)),
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(3))),
|
||||
enabledMouseCursor: enabledMouseCursor,
|
||||
disabledMouseCursor: disabledMouseCursor,
|
||||
visualDensity: VisualDensity.compact,
|
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
animationDuration: const Duration(milliseconds: 100),
|
||||
enableFeedback: true,
|
||||
alignment: Alignment.center,
|
||||
splashFactory: NoSplash.splashFactory,
|
||||
);
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Scaffold(
|
||||
body: Center(
|
||||
child: SegmentedButton<int>(
|
||||
style: styleFromStyle,
|
||||
segments: const <ButtonSegment<int>>[
|
||||
ButtonSegment<int>(value: 1, label: Text('1')),
|
||||
ButtonSegment<int>(value: 2, label: Text('2')),
|
||||
ButtonSegment<int>(value: 3, label: Text('3'), enabled: false),
|
||||
],
|
||||
selected: const <int>{2},
|
||||
onSelectionChanged: (Set<int> selected) { },
|
||||
selectedIcon: const Icon(Icons.alarm),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
// Test provided button style is applied to the enabled button segment.
|
||||
ButtonStyle? buttonStyle = tester.widget<TextButton>(find.byType(TextButton).first).style;
|
||||
expect(buttonStyle?.foregroundColor?.resolve(enabled), foregroundColor);
|
||||
expect(buttonStyle?.backgroundColor?.resolve(enabled), backgroundColor);
|
||||
expect(buttonStyle?.overlayColor, styleFromStyle.overlayColor);
|
||||
expect(buttonStyle?.surfaceTintColor, styleFromStyle.surfaceTintColor);
|
||||
expect(buttonStyle?.elevation, styleFromStyle.elevation);
|
||||
expect(buttonStyle?.textStyle, styleFromStyle.textStyle);
|
||||
expect(buttonStyle?.padding, styleFromStyle.padding);
|
||||
expect(buttonStyle?.mouseCursor?.resolve(enabled), enabledMouseCursor);
|
||||
expect(buttonStyle?.visualDensity, styleFromStyle.visualDensity);
|
||||
expect(buttonStyle?.tapTargetSize, styleFromStyle.tapTargetSize);
|
||||
expect(buttonStyle?.animationDuration, styleFromStyle.animationDuration);
|
||||
expect(buttonStyle?.enableFeedback, styleFromStyle.enableFeedback);
|
||||
expect(buttonStyle?.alignment, styleFromStyle.alignment);
|
||||
expect(buttonStyle?.splashFactory, styleFromStyle.splashFactory);
|
||||
|
||||
// Test provided button style is applied selected button segment.
|
||||
buttonStyle = tester.widget<TextButton>(find.byType(TextButton).at(1)).style;
|
||||
expect(buttonStyle?.foregroundColor?.resolve(selected), selectedForegroundColor);
|
||||
expect(buttonStyle?.backgroundColor?.resolve(selected), selectedBackgroundColor);
|
||||
expect(buttonStyle?.mouseCursor?.resolve(enabled), enabledMouseCursor);
|
||||
|
||||
// Test provided button style is applied disabled button segment.
|
||||
buttonStyle = tester.widget<TextButton>(find.byType(TextButton).last).style;
|
||||
expect(buttonStyle?.foregroundColor?.resolve(disabled), disabledForegroundColor);
|
||||
expect(buttonStyle?.backgroundColor?.resolve(disabled), disabledBackgroundColor);
|
||||
expect(buttonStyle?.mouseCursor?.resolve(disabled), disabledMouseCursor);
|
||||
|
||||
// Test provided button style is applied to the segmented button material.
|
||||
final Material material = tester.widget<Material>(find.descendant(
|
||||
of: find.byType(SegmentedButton<int>),
|
||||
matching: find.byType(Material),
|
||||
).first);
|
||||
expect(material.shape, styleFromStyle.shape?.resolve(enabled)?.copyWith(side: BorderSide.none));
|
||||
expect(material.elevation, styleFromStyle.elevation?.resolve(enabled));
|
||||
expect(material.shadowColor, styleFromStyle.shadowColor?.resolve(enabled));
|
||||
expect(material.surfaceTintColor, styleFromStyle.surfaceTintColor?.resolve(enabled));
|
||||
|
||||
// Test provided button style border is applied to the segmented button border.
|
||||
expect(
|
||||
find.byType(SegmentedButton<int>),
|
||||
paints..line(color: styleFromStyle.side?.resolve(enabled)?.color),
|
||||
);
|
||||
|
||||
// Test foreground color is applied to the overlay color.
|
||||
RenderObject overlayColor() {
|
||||
return tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
||||
}
|
||||
final TestGesture gesture = await tester.createGesture(
|
||||
kind: PointerDeviceKind.mouse,
|
||||
);
|
||||
await gesture.addPointer();
|
||||
await gesture.down(tester.getCenter(find.text('1')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(overlayColor(), paints..rect(color: foregroundColor.withOpacity(0.08)));
|
||||
});
|
||||
}
|
||||
|
||||
Set<MaterialState> enabled = const <MaterialState>{};
|
||||
Set<MaterialState> disabled = const <MaterialState>{ MaterialState.disabled };
|
||||
Set<MaterialState> selected = const <MaterialState>{ MaterialState.selected };
|
||||
|
Loading…
x
Reference in New Issue
Block a user