mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
fixes [Add missing `overlayColor` property in `styleFrom` methods](https://github.com/flutter/flutter/issues/146636) ### Code sample <details> <summary>expand to view the code sample</summary> ```dart import 'package:flutter/material.dart'; enum Sizes { extraSmall, small, medium, large, extraLarge } void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ Text('styleFrom(overlayColor: Colors.red)', style: Theme.of(context).textTheme.titleLarge), TextButton( style: TextButton.styleFrom(overlayColor: Colors.red), onPressed: () {}, child: const Text('TextButton'), ), IconButton( style: IconButton.styleFrom( overlayColor: Colors.red, ), onPressed: () {}, icon: const Icon(Icons.add), ), MenuBar( children: [ MenuItemButton( style: MenuItemButton.styleFrom(overlayColor: Colors.red), child: const Text('MenuItemButton'), onPressed: () {}, ), SubmenuButton( style: SubmenuButton.styleFrom(overlayColor: Colors.red), menuChildren: [ MenuItemButton( child: const Text('MenuItemButton'), onPressed: () {}, ), ], child: const Text('SubmenuButton'), ), ], ), SegmentedButton<Sizes>( style: SegmentedButton.styleFrom(overlayColor: Colors.red), segments: const <ButtonSegment<Sizes>>[ ButtonSegment<Sizes>( value: Sizes.extraSmall, label: Text('XS')), ButtonSegment<Sizes>(value: Sizes.small, label: Text('S')), ButtonSegment<Sizes>(value: Sizes.medium, label: Text('M')), ButtonSegment<Sizes>( value: Sizes.large, label: Text('L'), ), ButtonSegment<Sizes>( value: Sizes.extraLarge, label: Text('XL')), ], selected: const {Sizes.medium}, onSelectionChanged: (Set<Sizes> newSelection) {}, multiSelectionEnabled: true, ), ], ), ), ), ); } } ``` </details> ### Preview 
574 lines
23 KiB
Dart
574 lines
23 KiB
Dart
// 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/foundation.dart';
|
|
import 'package:flutter/gestures.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
void main() {
|
|
RenderObject getOverlayColor(WidgetTester tester) {
|
|
return tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
|
}
|
|
|
|
test('SegmentedButtonThemeData copyWith, ==, hashCode basics', () {
|
|
expect(const SegmentedButtonThemeData(), const SegmentedButtonThemeData().copyWith());
|
|
expect(const SegmentedButtonThemeData().hashCode, const SegmentedButtonThemeData().copyWith().hashCode);
|
|
|
|
const SegmentedButtonThemeData custom = SegmentedButtonThemeData(
|
|
style: ButtonStyle(backgroundColor: MaterialStatePropertyAll<Color>(Colors.green)),
|
|
selectedIcon: Icon(Icons.error),
|
|
);
|
|
final SegmentedButtonThemeData copy = const SegmentedButtonThemeData().copyWith(
|
|
style: custom.style,
|
|
selectedIcon: custom.selectedIcon,
|
|
);
|
|
expect(copy, custom);
|
|
});
|
|
|
|
test('SegmentedButtonThemeData lerp special cases', () {
|
|
expect(SegmentedButtonThemeData.lerp(null, null, 0), const SegmentedButtonThemeData());
|
|
const SegmentedButtonThemeData theme = SegmentedButtonThemeData();
|
|
expect(identical(SegmentedButtonThemeData.lerp(theme, theme, 0.5), theme), true);
|
|
});
|
|
|
|
testWidgets('Default SegmentedButtonThemeData debugFillProperties', (WidgetTester tester) async {
|
|
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
|
const SegmentedButtonThemeData().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('With no other configuration, defaults are used', (WidgetTester tester) async {
|
|
final ThemeData theme = ThemeData(useMaterial3: true);
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: theme,
|
|
home: Scaffold(
|
|
body: Center(
|
|
child: SegmentedButton<int>(
|
|
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) { },
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// Test first segment, should be enabled
|
|
{
|
|
final Finder text = find.text('1');
|
|
final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first;
|
|
final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.check));
|
|
final Material material = tester.widget<Material>(parent);
|
|
expect(material.color, Colors.transparent);
|
|
expect(material.shape, const RoundedRectangleBorder());
|
|
expect(material.textStyle!.color, theme.colorScheme.onSurface);
|
|
expect(material.textStyle!.fontFamily, 'Roboto');
|
|
expect(material.textStyle!.fontSize, 14);
|
|
expect(material.textStyle!.fontWeight, FontWeight.w500);
|
|
expect(selectedIcon, findsNothing);
|
|
}
|
|
|
|
// Test second segment, should be enabled and selected
|
|
{
|
|
final Finder text = find.text('2');
|
|
final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first;
|
|
final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.check));
|
|
final Material material = tester.widget<Material>(parent);
|
|
expect(material.color, theme.colorScheme.secondaryContainer);
|
|
expect(material.shape, const RoundedRectangleBorder());
|
|
expect(material.textStyle!.color, theme.colorScheme.onSecondaryContainer);
|
|
expect(material.textStyle!.fontFamily, 'Roboto');
|
|
expect(material.textStyle!.fontSize, 14);
|
|
expect(material.textStyle!.fontWeight, FontWeight.w500);
|
|
expect(selectedIcon, findsOneWidget);
|
|
}
|
|
|
|
// Test last segment, should be disabled
|
|
{
|
|
final Finder text = find.text('3');
|
|
final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first;
|
|
final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.check));
|
|
final Material material = tester.widget<Material>(parent);
|
|
expect(material.color, Colors.transparent);
|
|
expect(material.shape, const RoundedRectangleBorder());
|
|
expect(material.textStyle!.color, theme.colorScheme.onSurface.withOpacity(0.38));
|
|
expect(material.textStyle!.fontFamily, 'Roboto');
|
|
expect(material.textStyle!.fontSize, 14);
|
|
expect(material.textStyle!.fontWeight, FontWeight.w500);
|
|
expect(selectedIcon, findsNothing);
|
|
}
|
|
});
|
|
|
|
testWidgets('ThemeData.segmentedButtonTheme overrides defaults', (WidgetTester tester) async {
|
|
final ThemeData theme = ThemeData(
|
|
useMaterial3: true,
|
|
segmentedButtonTheme: SegmentedButtonThemeData(
|
|
style: ButtonStyle(
|
|
backgroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.disabled)) {
|
|
return Colors.blue;
|
|
}
|
|
if (states.contains(MaterialState.selected)) {
|
|
return Colors.purple;
|
|
}
|
|
return null;
|
|
}),
|
|
foregroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.disabled)) {
|
|
return Colors.yellow;
|
|
}
|
|
if (states.contains(MaterialState.selected)) {
|
|
return Colors.brown;
|
|
} else {
|
|
return Colors.cyan;
|
|
}
|
|
}),
|
|
),
|
|
selectedIcon: const Icon(Icons.error),
|
|
),
|
|
);
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: theme,
|
|
home: Scaffold(
|
|
body: Center(
|
|
child: SegmentedButton<int>(
|
|
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) { },
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// Test first segment, should be enabled
|
|
{
|
|
final Finder text = find.text('1');
|
|
final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first;
|
|
final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.error));
|
|
final Material material = tester.widget<Material>(parent);
|
|
expect(material.color, Colors.transparent);
|
|
expect(material.shape, const RoundedRectangleBorder());
|
|
expect(material.textStyle!.color, Colors.cyan);
|
|
expect(material.textStyle!.fontFamily, 'Roboto');
|
|
expect(material.textStyle!.fontSize, 14);
|
|
expect(material.textStyle!.fontWeight, FontWeight.w500);
|
|
expect(selectedIcon, findsNothing);
|
|
}
|
|
|
|
// Test second segment, should be enabled and selected
|
|
{
|
|
final Finder text = find.text('2');
|
|
final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first;
|
|
final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.error));
|
|
final Material material = tester.widget<Material>(parent);
|
|
expect(material.color, Colors.purple);
|
|
expect(material.shape, const RoundedRectangleBorder());
|
|
expect(material.textStyle!.color, Colors.brown);
|
|
expect(material.textStyle!.fontFamily, 'Roboto');
|
|
expect(material.textStyle!.fontSize, 14);
|
|
expect(material.textStyle!.fontWeight, FontWeight.w500);
|
|
expect(selectedIcon, findsOneWidget);
|
|
}
|
|
|
|
// Test last segment, should be disabled
|
|
{
|
|
final Finder text = find.text('3');
|
|
final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first;
|
|
final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.error));
|
|
final Material material = tester.widget<Material>(parent);
|
|
expect(material.color, Colors.blue);
|
|
expect(material.shape, const RoundedRectangleBorder());
|
|
expect(material.textStyle!.color, Colors.yellow);
|
|
expect(material.textStyle!.fontFamily, 'Roboto');
|
|
expect(material.textStyle!.fontSize, 14);
|
|
expect(material.textStyle!.fontWeight, FontWeight.w500);
|
|
expect(selectedIcon, findsNothing);
|
|
}
|
|
});
|
|
|
|
testWidgets('SegmentedButtonTheme overrides ThemeData and defaults', (WidgetTester tester) async {
|
|
final SegmentedButtonThemeData global = SegmentedButtonThemeData(
|
|
style: ButtonStyle(
|
|
backgroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.disabled)) {
|
|
return Colors.blue;
|
|
}
|
|
if (states.contains(MaterialState.selected)) {
|
|
return Colors.purple;
|
|
}
|
|
return null;
|
|
}),
|
|
foregroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.disabled)) {
|
|
return Colors.yellow;
|
|
}
|
|
if (states.contains(MaterialState.selected)) {
|
|
return Colors.brown;
|
|
} else {
|
|
return Colors.cyan;
|
|
}
|
|
}),
|
|
),
|
|
selectedIcon: const Icon(Icons.error),
|
|
);
|
|
final SegmentedButtonThemeData segmentedTheme = SegmentedButtonThemeData(
|
|
style: ButtonStyle(
|
|
backgroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.disabled)) {
|
|
return Colors.lightBlue;
|
|
}
|
|
if (states.contains(MaterialState.selected)) {
|
|
return Colors.lightGreen;
|
|
}
|
|
return null;
|
|
}),
|
|
foregroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.disabled)) {
|
|
return Colors.lime;
|
|
}
|
|
if (states.contains(MaterialState.selected)) {
|
|
return Colors.amber;
|
|
} else {
|
|
return Colors.deepPurple;
|
|
}
|
|
}),
|
|
),
|
|
selectedIcon: const Icon(Icons.plus_one),
|
|
);
|
|
final ThemeData theme = ThemeData(
|
|
useMaterial3: true,
|
|
segmentedButtonTheme: global,
|
|
);
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: theme,
|
|
home: SegmentedButtonTheme(
|
|
data: segmentedTheme,
|
|
child: Scaffold(
|
|
body: Center(
|
|
child: SegmentedButton<int>(
|
|
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) { },
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// Test first segment, should be enabled
|
|
{
|
|
final Finder text = find.text('1');
|
|
final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first;
|
|
final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.plus_one));
|
|
final Material material = tester.widget<Material>(parent);
|
|
expect(material.animationDuration, const Duration(milliseconds: 200));
|
|
expect(material.borderRadius, null);
|
|
expect(material.color, Colors.transparent);
|
|
expect(material.shape, const RoundedRectangleBorder());
|
|
expect(material.textStyle!.color, Colors.deepPurple);
|
|
expect(material.textStyle!.fontFamily, 'Roboto');
|
|
expect(material.textStyle!.fontSize, 14);
|
|
expect(material.textStyle!.fontWeight, FontWeight.w500);
|
|
expect(selectedIcon, findsNothing);
|
|
}
|
|
|
|
// Test second segment, should be enabled and selected
|
|
{
|
|
final Finder text = find.text('2');
|
|
final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first;
|
|
final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.plus_one));
|
|
final Material material = tester.widget<Material>(parent);
|
|
expect(material.animationDuration, const Duration(milliseconds: 200));
|
|
expect(material.borderRadius, null);
|
|
expect(material.color, Colors.lightGreen);
|
|
expect(material.shape, const RoundedRectangleBorder());
|
|
expect(material.textStyle!.color, Colors.amber);
|
|
expect(material.textStyle!.fontFamily, 'Roboto');
|
|
expect(material.textStyle!.fontSize, 14);
|
|
expect(material.textStyle!.fontWeight, FontWeight.w500);
|
|
expect(selectedIcon, findsOneWidget);
|
|
}
|
|
|
|
// Test last segment, should be disabled
|
|
{
|
|
final Finder text = find.text('3');
|
|
final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first;
|
|
final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.plus_one));
|
|
final Material material = tester.widget<Material>(parent);
|
|
expect(material.animationDuration, const Duration(milliseconds: 200));
|
|
expect(material.borderRadius, null);
|
|
expect(material.color, Colors.lightBlue);
|
|
expect(material.shape, const RoundedRectangleBorder());
|
|
expect(material.textStyle!.color, Colors.lime);
|
|
expect(material.textStyle!.fontFamily, 'Roboto');
|
|
expect(material.textStyle!.fontSize, 14);
|
|
expect(material.textStyle!.fontWeight, FontWeight.w500);
|
|
expect(selectedIcon, findsNothing);
|
|
}
|
|
});
|
|
|
|
testWidgets('Widget parameters overrides SegmentedTheme, ThemeData and defaults', (WidgetTester tester) async {
|
|
final SegmentedButtonThemeData global = SegmentedButtonThemeData(
|
|
style: ButtonStyle(
|
|
backgroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.disabled)) {
|
|
return Colors.blue;
|
|
}
|
|
if (states.contains(MaterialState.selected)) {
|
|
return Colors.purple;
|
|
}
|
|
return null;
|
|
}),
|
|
foregroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.disabled)) {
|
|
return Colors.yellow;
|
|
}
|
|
if (states.contains(MaterialState.selected)) {
|
|
return Colors.brown;
|
|
} else {
|
|
return Colors.cyan;
|
|
}
|
|
}),
|
|
),
|
|
selectedIcon: const Icon(Icons.error),
|
|
);
|
|
final SegmentedButtonThemeData segmentedTheme = SegmentedButtonThemeData(
|
|
style: ButtonStyle(
|
|
backgroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.disabled)) {
|
|
return Colors.lightBlue;
|
|
}
|
|
if (states.contains(MaterialState.selected)) {
|
|
return Colors.lightGreen;
|
|
}
|
|
return null;
|
|
}),
|
|
foregroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.disabled)) {
|
|
return Colors.lime;
|
|
}
|
|
if (states.contains(MaterialState.selected)) {
|
|
return Colors.amber;
|
|
} else {
|
|
return Colors.deepPurple;
|
|
}
|
|
}),
|
|
),
|
|
selectedIcon: const Icon(Icons.plus_one),
|
|
);
|
|
final ThemeData theme = ThemeData(
|
|
useMaterial3: true,
|
|
segmentedButtonTheme: global,
|
|
);
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: theme,
|
|
home: SegmentedButtonTheme(
|
|
data: segmentedTheme,
|
|
child: Scaffold(
|
|
body: Center(
|
|
child: SegmentedButton<int>(
|
|
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) { },
|
|
style: ButtonStyle(
|
|
backgroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.disabled)) {
|
|
return Colors.black12;
|
|
}
|
|
if (states.contains(MaterialState.selected)) {
|
|
return Colors.grey;
|
|
}
|
|
return null;
|
|
}),
|
|
foregroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.disabled)) {
|
|
return Colors.amberAccent;
|
|
}
|
|
if (states.contains(MaterialState.selected)) {
|
|
return Colors.deepOrange;
|
|
} else {
|
|
return Colors.deepPurpleAccent;
|
|
}
|
|
}),
|
|
),
|
|
selectedIcon: const Icon(Icons.alarm),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// Test first segment, should be enabled
|
|
{
|
|
final Finder text = find.text('1');
|
|
final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first;
|
|
final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.alarm));
|
|
final Material material = tester.widget<Material>(parent);
|
|
expect(material.animationDuration, const Duration(milliseconds: 200));
|
|
expect(material.borderRadius, null);
|
|
expect(material.color, Colors.transparent);
|
|
expect(material.shape, const RoundedRectangleBorder());
|
|
expect(material.textStyle!.color, Colors.deepPurpleAccent);
|
|
expect(material.textStyle!.fontFamily, 'Roboto');
|
|
expect(material.textStyle!.fontSize, 14);
|
|
expect(material.textStyle!.fontWeight, FontWeight.w500);
|
|
expect(selectedIcon, findsNothing);
|
|
}
|
|
|
|
// Test second segment, should be enabled and selected
|
|
{
|
|
final Finder text = find.text('2');
|
|
final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first;
|
|
final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.alarm));
|
|
final Material material = tester.widget<Material>(parent);
|
|
expect(material.animationDuration, const Duration(milliseconds: 200));
|
|
expect(material.borderRadius, null);
|
|
expect(material.color, Colors.grey);
|
|
expect(material.shape, const RoundedRectangleBorder());
|
|
expect(material.textStyle!.color, Colors.deepOrange);
|
|
expect(material.textStyle!.fontFamily, 'Roboto');
|
|
expect(material.textStyle!.fontSize, 14);
|
|
expect(material.textStyle!.fontWeight, FontWeight.w500);
|
|
expect(selectedIcon, findsOneWidget);
|
|
}
|
|
|
|
// Test last segment, should be disabled
|
|
{
|
|
final Finder text = find.text('3');
|
|
final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first;
|
|
final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.alarm));
|
|
final Material material = tester.widget<Material>(parent);
|
|
expect(material.animationDuration, const Duration(milliseconds: 200));
|
|
expect(material.borderRadius, null);
|
|
expect(material.color, Colors.black12);
|
|
expect(material.shape, const RoundedRectangleBorder());
|
|
expect(material.textStyle!.color, Colors.amberAccent);
|
|
expect(material.textStyle!.fontFamily, 'Roboto');
|
|
expect(material.textStyle!.fontSize, 14);
|
|
expect(material.textStyle!.fontWeight, FontWeight.w500);
|
|
expect(selectedIcon, findsNothing);
|
|
}
|
|
});
|
|
|
|
testWidgets('SegmentedButtonTheme SegmentedButton.styleFrom overlayColor overrides default overlay color', (WidgetTester tester) async {
|
|
const Color overlayColor = Color(0xffff0000);
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: ThemeData(
|
|
segmentedButtonTheme: SegmentedButtonThemeData(
|
|
style: SegmentedButton.styleFrom(overlayColor: overlayColor),
|
|
),
|
|
),
|
|
home: Scaffold(
|
|
body: Center(
|
|
child: SegmentedButton<int>(
|
|
segments: const <ButtonSegment<int>>[
|
|
ButtonSegment<int>(
|
|
value: 0,
|
|
label: Text('Option 1'),
|
|
),
|
|
ButtonSegment<int>(
|
|
value: 1,
|
|
label: Text('Option 2'),
|
|
),
|
|
],
|
|
onSelectionChanged: (Set<int> selected) {},
|
|
selected: const <int>{1},
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// Hovered selected segment,
|
|
Offset center = tester.getCenter(find.text('Option 1'));
|
|
final TestGesture gesture = await tester.createGesture(
|
|
kind: PointerDeviceKind.mouse,
|
|
);
|
|
await gesture.addPointer();
|
|
await gesture.moveTo(center);
|
|
await tester.pumpAndSettle();
|
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.08)));
|
|
|
|
// Hovered unselected segment,
|
|
center = tester.getCenter(find.text('Option 2'));
|
|
await gesture.moveTo(center);
|
|
await tester.pumpAndSettle();
|
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.08)));
|
|
|
|
// Highlighted unselected segment (pressed).
|
|
center = tester.getCenter(find.text('Option 1'));
|
|
await gesture.down(center);
|
|
await tester.pumpAndSettle();
|
|
expect(
|
|
getOverlayColor(tester),
|
|
paints
|
|
..rect(color: overlayColor.withOpacity(0.08))
|
|
..rect(color: overlayColor.withOpacity(0.1)),
|
|
);
|
|
// Remove pressed and hovered states,
|
|
await gesture.up();
|
|
await tester.pumpAndSettle();
|
|
await gesture.moveTo(const Offset(0, 50));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Highlighted selected segment (pressed)
|
|
center = tester.getCenter(find.text('Option 2'));
|
|
await gesture.down(center);
|
|
await tester.pumpAndSettle();
|
|
expect(
|
|
getOverlayColor(tester),
|
|
paints
|
|
..rect(color: overlayColor.withOpacity(0.08))
|
|
..rect(color: overlayColor.withOpacity(0.1)),
|
|
);
|
|
// Remove pressed and hovered states,
|
|
await gesture.up();
|
|
await tester.pumpAndSettle();
|
|
await gesture.moveTo(const Offset(0, 50));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Focused unselected segment.
|
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
|
await tester.pumpAndSettle();
|
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.1)));
|
|
|
|
// Focused selected segment.
|
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
|
await tester.pumpAndSettle();
|
|
expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.1)));
|
|
});
|
|
}
|