mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
ToggleButtons: Add interactive example (#100124)
This commit is contained in:
parent
99769b0f89
commit
4ffc41ad10
158
examples/api/lib/material/toggle_buttons/toggle_buttons.0.dart
Normal file
158
examples/api/lib/material/toggle_buttons/toggle_buttons.0.dart
Normal file
@ -0,0 +1,158 @@
|
||||
// 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.
|
||||
|
||||
// Flutter code sample for ToggleButtons
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
const List<Widget> fruits = <Widget>[
|
||||
Text('Apple'),
|
||||
Text('Banana'),
|
||||
Text('Orange')
|
||||
];
|
||||
|
||||
const List<Widget> vegetables = <Widget>[
|
||||
Text('Tomatoes'),
|
||||
Text('Potatoes'),
|
||||
Text('Carrots')
|
||||
];
|
||||
|
||||
const List<Widget> icons = <Widget>[
|
||||
Icon(Icons.sunny),
|
||||
Icon(Icons.cloud),
|
||||
Icon(Icons.ac_unit),
|
||||
];
|
||||
|
||||
void main() => runApp(const MyApp());
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({Key? key}) : super(key: key);
|
||||
|
||||
static const String _title = 'ToggleButtons Sample';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const MaterialApp(
|
||||
title: _title,
|
||||
home: ToggleButtonsSample(title: _title),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ToggleButtonsSample extends StatefulWidget {
|
||||
const ToggleButtonsSample({Key? key, required this.title}) : super(key: key);
|
||||
|
||||
final String title;
|
||||
|
||||
@override
|
||||
State<ToggleButtonsSample> createState() => _ToggleButtonsSampleState();
|
||||
}
|
||||
|
||||
class _ToggleButtonsSampleState extends State<ToggleButtonsSample> {
|
||||
final List<bool> _selectedFruits = <bool>[true, false, false];
|
||||
final List<bool> _selectedVegetables = <bool>[false, true, false];
|
||||
final List<bool> _selectedWeather = <bool>[false, false, true];
|
||||
bool vertical = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ThemeData theme = Theme.of(context);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text(widget.title)),
|
||||
body: Center(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
// ToggleButtons with a single selection.
|
||||
Text('Single-select', style: theme.textTheme.subtitle2),
|
||||
const SizedBox(height: 5),
|
||||
ToggleButtons(
|
||||
direction: vertical ? Axis.vertical : Axis.horizontal,
|
||||
onPressed: (int index) {
|
||||
setState(() {
|
||||
// The button that is tapped is set to true, and the others to false.
|
||||
for (int i = 0; i < _selectedFruits.length; i++) {
|
||||
_selectedFruits[i] = i == index;
|
||||
}
|
||||
});
|
||||
},
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
selectedBorderColor: Colors.red[700],
|
||||
selectedColor: Colors.white,
|
||||
fillColor: Colors.red[200],
|
||||
color: Colors.red[400],
|
||||
constraints: const BoxConstraints(
|
||||
minHeight: 40.0,
|
||||
minWidth: 80.0,
|
||||
),
|
||||
isSelected: _selectedFruits,
|
||||
children: fruits,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
// ToggleButtons with a multiple selection.
|
||||
Text('Multi-select', style: theme.textTheme.subtitle2),
|
||||
const SizedBox(height: 5),
|
||||
ToggleButtons(
|
||||
direction: vertical ? Axis.vertical : Axis.horizontal,
|
||||
onPressed: (int index) {
|
||||
// All buttons are selectable.
|
||||
setState(() {
|
||||
_selectedVegetables[index] =
|
||||
!_selectedVegetables[index];
|
||||
});
|
||||
},
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
selectedBorderColor: Colors.green[700],
|
||||
selectedColor: Colors.white,
|
||||
fillColor: Colors.green[200],
|
||||
color: Colors.green[400],
|
||||
constraints: const BoxConstraints(
|
||||
minHeight: 40.0,
|
||||
minWidth: 80.0,
|
||||
),
|
||||
isSelected: _selectedVegetables,
|
||||
children: vegetables,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
// ToggleButtons with icons only.
|
||||
Text('Icon-only', style: theme.textTheme.subtitle2),
|
||||
const SizedBox(height: 5),
|
||||
ToggleButtons(
|
||||
direction: vertical ? Axis.vertical : Axis.horizontal,
|
||||
onPressed: (int index) {
|
||||
setState(() {
|
||||
// The button that is tapped is set to true, and the others to false.
|
||||
for (int i = 0; i < _selectedWeather.length; i++) {
|
||||
_selectedWeather[i] = i == index;
|
||||
}
|
||||
});
|
||||
},
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
selectedBorderColor: Colors.blue[700],
|
||||
selectedColor: Colors.white,
|
||||
fillColor: Colors.blue[200],
|
||||
color: Colors.blue[400],
|
||||
isSelected: _selectedWeather,
|
||||
children: icons,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
// When the button is pressed, ToggleButtons direction is changed.
|
||||
vertical = !vertical;
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.screen_rotation_outlined),
|
||||
label: Text(vertical ? 'Horizontal' : 'Vertical'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,118 @@
|
||||
// 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/toggle_buttons/toggle_buttons.0.dart' as example;
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
|
||||
testWidgets('Single-select ToggleButtons', (WidgetTester tester) async {
|
||||
TextButton findButton(String text) {
|
||||
return tester.widget<TextButton>(find.widgetWithText(TextButton, text));
|
||||
}
|
||||
await tester.pumpWidget(
|
||||
const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: example.MyApp(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
TextButton firstButton = findButton('Apple');
|
||||
TextButton secondButton = findButton('Banana');
|
||||
TextButton thirdButton = findButton('Orange');
|
||||
|
||||
/// First button is selected.
|
||||
expect(firstButton.style!.backgroundColor!.resolve(enabled), const Color(0xffef9a9a));
|
||||
expect(secondButton.style!.backgroundColor!.resolve(enabled), const Color(0x00ffffff));
|
||||
expect(thirdButton.style!.backgroundColor!.resolve(enabled), const Color(0x00ffffff));
|
||||
|
||||
/// Tap on second button.
|
||||
await tester.tap(find.widgetWithText(TextButton, 'Banana'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
firstButton = findButton('Apple');
|
||||
secondButton = findButton('Banana');
|
||||
thirdButton = findButton('Orange');
|
||||
|
||||
/// Only second button is selected.
|
||||
expect(firstButton.style!.backgroundColor!.resolve(enabled), const Color(0x00ffffff));
|
||||
expect(secondButton.style!.backgroundColor!.resolve(enabled), const Color(0xffef9a9a));
|
||||
expect(thirdButton.style!.backgroundColor!.resolve(enabled), const Color(0x00ffffff));
|
||||
});
|
||||
|
||||
testWidgets('Multi-select ToggleButtons', (WidgetTester tester) async {
|
||||
TextButton findButton(String text) {
|
||||
return tester.widget<TextButton>(find.widgetWithText(TextButton, text));
|
||||
}
|
||||
await tester.pumpWidget(
|
||||
const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: example.MyApp(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
TextButton firstButton = findButton('Tomatoes');
|
||||
TextButton secondButton = findButton('Potatoes');
|
||||
TextButton thirdButton = findButton('Carrots');
|
||||
|
||||
/// Second button is selected.
|
||||
expect(firstButton.style!.backgroundColor!.resolve(enabled), const Color(0x00ffffff));
|
||||
expect(secondButton.style!.backgroundColor!.resolve(enabled), const Color(0xffa5d6a7));
|
||||
expect(thirdButton.style!.backgroundColor!.resolve(enabled), const Color(0x00ffffff));
|
||||
|
||||
/// Tap on other two buttons.
|
||||
await tester.tap(find.widgetWithText(TextButton, 'Tomatoes'));
|
||||
await tester.tap(find.widgetWithText(TextButton, 'Carrots'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
firstButton = findButton('Tomatoes');
|
||||
secondButton = findButton('Potatoes');
|
||||
thirdButton = findButton('Carrots');
|
||||
|
||||
/// All buttons are selected.
|
||||
expect(firstButton.style!.backgroundColor!.resolve(enabled), const Color(0xffa5d6a7));
|
||||
expect(secondButton.style!.backgroundColor!.resolve(enabled), const Color(0xffa5d6a7));
|
||||
expect(thirdButton.style!.backgroundColor!.resolve(enabled), const Color(0xffa5d6a7));
|
||||
});
|
||||
|
||||
testWidgets('Icon-only ToggleButtons', (WidgetTester tester) async {
|
||||
TextButton findButton(IconData iconData) {
|
||||
return tester.widget<TextButton>(find.widgetWithIcon(TextButton, iconData));
|
||||
}
|
||||
await tester.pumpWidget(
|
||||
const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: example.MyApp(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
TextButton firstButton = findButton(Icons.sunny);
|
||||
TextButton secondButton = findButton(Icons.cloud);
|
||||
TextButton thirdButton = findButton(Icons.ac_unit);
|
||||
|
||||
/// Third button is selected.
|
||||
expect(firstButton.style!.backgroundColor!.resolve(enabled), const Color(0x00ffffff));
|
||||
expect(secondButton.style!.backgroundColor!.resolve(enabled), const Color(0x00ffffff));
|
||||
expect(thirdButton.style!.backgroundColor!.resolve(enabled), const Color(0xff90caf9));
|
||||
|
||||
/// Tap on the first button.
|
||||
await tester.tap(find.widgetWithIcon(TextButton, Icons.sunny));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
firstButton = findButton(Icons.sunny);
|
||||
secondButton = findButton(Icons.cloud);
|
||||
thirdButton = findButton(Icons.ac_unit);
|
||||
|
||||
/// First button os selected.
|
||||
expect(firstButton.style!.backgroundColor!.resolve(enabled), const Color(0xff90caf9));
|
||||
expect(secondButton.style!.backgroundColor!.resolve(enabled), const Color(0x00ffffff));
|
||||
expect(thirdButton.style!.backgroundColor!.resolve(enabled), const Color(0x00ffffff));
|
||||
});
|
||||
}
|
||||
|
||||
Set<MaterialState> enabled = <MaterialState>{ };
|
||||
@ -28,6 +28,12 @@ import 'toggle_buttons_theme.dart';
|
||||
///
|
||||
/// {@youtube 560 315 https://www.youtube.com/watch?v=kVEguaQWGAY}
|
||||
///
|
||||
/// {@tool dartpad}
|
||||
/// This example showcase [ToggleButtons] in various configurations.
|
||||
///
|
||||
/// ** See code in examples/api/lib/material/toggle_buttons/toggle_buttons.0.dart **
|
||||
/// {@end-tool}
|
||||
///
|
||||
/// ## Customizing toggle buttons
|
||||
/// Each toggle's behavior can be configured by the [onPressed] callback, which
|
||||
/// can update the [isSelected] list however it wants to.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user