| // 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 '../../gallery/demo.dart'; |
| |
| const String _elevatedText = |
| 'Elevated buttons add dimension to mostly flat layouts. They emphasize ' |
| 'functions on busy or wide spaces.'; |
| |
| const String _elevatedCode = 'buttons_elevated'; |
| |
| const String _textText = 'A text button displays an ink splash on press ' |
| 'but does not lift. Use text buttons on toolbars, in dialogs and ' |
| 'inline with padding'; |
| |
| const String _textCode = 'buttons_text'; |
| |
| const String _outlinedText = |
| 'Outlined buttons become opaque and elevate when pressed. They are often ' |
| 'paired with elevated buttons to indicate an alternative, secondary action.'; |
| |
| const String _outlinedCode = 'buttons_outlined'; |
| |
| const String _dropdownText = |
| "A dropdown button displays a menu that's used to select a value from a " |
| 'small set of values. The button displays the current value and a down ' |
| 'arrow.'; |
| |
| const String _dropdownCode = 'buttons_dropdown'; |
| |
| const String _iconText = |
| 'IconButtons are appropriate for toggle buttons that allow a single choice ' |
| "to be selected or deselected, such as adding or removing an item's star."; |
| |
| const String _iconCode = 'buttons_icon'; |
| |
| const String _actionText = |
| 'Floating action buttons are used for a promoted action. They are ' |
| 'distinguished by a circled icon floating above the UI and can have motion ' |
| 'behaviors that include morphing, launching, and a transferring anchor ' |
| 'point.'; |
| |
| const String _actionCode = 'buttons_action'; |
| |
| class ButtonsDemo extends StatefulWidget { |
| const ButtonsDemo({super.key}); |
| |
| static const String routeName = '/material/buttons'; |
| |
| @override |
| State<ButtonsDemo> createState() => _ButtonsDemoState(); |
| } |
| |
| class _ButtonsDemoState extends State<ButtonsDemo> { |
| OutlinedBorder? _buttonShape; |
| |
| @override |
| Widget build(BuildContext context) { |
| final List<ComponentDemoTabData> demos = <ComponentDemoTabData>[ |
| ComponentDemoTabData( |
| tabName: 'ELEVATED', |
| description: _elevatedText, |
| demoWidget: buildElevatedButton(_buttonShape), |
| exampleCodeTag: _elevatedCode, |
| documentationUrl: 'https://api.flutter.dev/flutter/material/ElevatedButton-class.html', |
| ), |
| ComponentDemoTabData( |
| tabName: 'TEXT', |
| description: _textText, |
| demoWidget: buildTextButton(_buttonShape), |
| exampleCodeTag: _textCode, |
| documentationUrl: 'https://api.flutter.dev/flutter/material/TextButton-class.html', |
| ), |
| ComponentDemoTabData( |
| tabName: 'OUTLINED', |
| description: _outlinedText, |
| demoWidget: buildOutlinedButton(_buttonShape), |
| exampleCodeTag: _outlinedCode, |
| documentationUrl: 'https://api.flutter.dev/flutter/material/OutlinedButton-class.html', |
| ), |
| ComponentDemoTabData( |
| tabName: 'DROPDOWN', |
| description: _dropdownText, |
| demoWidget: buildDropdownButton(), |
| exampleCodeTag: _dropdownCode, |
| documentationUrl: 'https://api.flutter.dev/flutter/material/DropdownButton-class.html', |
| ), |
| ComponentDemoTabData( |
| tabName: 'ICON', |
| description: _iconText, |
| demoWidget: buildIconButton(), |
| exampleCodeTag: _iconCode, |
| documentationUrl: 'https://api.flutter.dev/flutter/material/IconButton-class.html', |
| ), |
| ComponentDemoTabData( |
| tabName: 'ACTION', |
| description: _actionText, |
| demoWidget: buildActionButton(), |
| exampleCodeTag: _actionCode, |
| documentationUrl: 'https://api.flutter.dev/flutter/material/FloatingActionButton-class.html', |
| ), |
| ]; |
| |
| return TabbedComponentDemoScaffold( |
| title: 'Buttons', |
| demos: demos, |
| actions: <Widget>[ |
| IconButton( |
| icon: const Icon(Icons.sentiment_very_satisfied, semanticLabel: 'Update shape'), |
| onPressed: () { |
| setState(() { |
| _buttonShape = _buttonShape == null ? const StadiumBorder() : null; |
| }); |
| }, |
| ), |
| ], |
| ); |
| } |
| |
| Widget buildElevatedButton(OutlinedBorder? shape) { |
| final ButtonStyle style = ElevatedButton.styleFrom(shape: shape); |
| return Align( |
| alignment: const Alignment(0.0, -0.2), |
| child: Column( |
| mainAxisSize: MainAxisSize.min, |
| children: <Widget>[ |
| const SizedBox(height: 2), |
| OverflowBar( |
| spacing: 8, |
| children: <Widget>[ |
| ElevatedButton( |
| style: style, |
| child: const Text('ELEVATED BUTTON', semanticsLabel: 'ELEVATED BUTTON 1'), |
| onPressed: () { |
| // Perform some action |
| }, |
| ), |
| const ElevatedButton( |
| onPressed: null, |
| child: Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 1'), |
| ), |
| ], |
| ), |
| const SizedBox(height: 16), |
| OverflowBar( |
| spacing: 8, |
| children: <Widget>[ |
| ElevatedButton.icon( |
| style: style, |
| icon: const Icon(Icons.add, size: 18.0), |
| label: const Text('ELEVATED BUTTON', semanticsLabel: 'ELEVATED BUTTON 2'), |
| onPressed: () { |
| // Perform some action |
| }, |
| ), |
| ElevatedButton.icon( |
| style: style, |
| icon: const Icon(Icons.add, size: 18.0), |
| label: const Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 2'), |
| onPressed: () {}, |
| ), |
| ], |
| ), |
| ], |
| ), |
| ); |
| } |
| |
| Widget buildTextButton(OutlinedBorder? shape) { |
| final ButtonStyle style = ElevatedButton.styleFrom(shape: shape); |
| return Align( |
| alignment: const Alignment(0.0, -0.2), |
| child: Column( |
| mainAxisSize: MainAxisSize.min, |
| children: <Widget>[ |
| const SizedBox(height: 2), |
| OverflowBar( |
| spacing: 8, |
| children: <Widget>[ |
| TextButton( |
| style: style, |
| child: const Text('TEXT BUTTON', semanticsLabel: 'TEXT BUTTON 1'), |
| onPressed: () { |
| // Perform some action |
| }, |
| ), |
| const TextButton( |
| onPressed: null, |
| child: Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 3',), |
| ), |
| ], |
| ), |
| OverflowBar( |
| spacing: 8, |
| children: <Widget>[ |
| TextButton.icon( |
| style: style, |
| icon: const Icon(Icons.add_circle_outline, size: 18.0), |
| label: const Text('TEXT BUTTON', semanticsLabel: 'TEXT BUTTON 2'), |
| onPressed: () { |
| // Perform some action |
| }, |
| ), |
| TextButton.icon( |
| style: style, |
| icon: const Icon(Icons.add_circle_outline, size: 18.0), |
| label: const Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 4'), |
| onPressed: () {}, |
| ), |
| ], |
| ), |
| ], |
| ), |
| ); |
| } |
| |
| Widget buildOutlinedButton(OutlinedBorder? shape) { |
| final ButtonStyle style = ElevatedButton.styleFrom(shape: shape); |
| return Align( |
| alignment: const Alignment(0.0, -0.2), |
| child: Column( |
| mainAxisSize: MainAxisSize.min, |
| children: <Widget>[ |
| const SizedBox(height: 2), |
| OverflowBar( |
| spacing: 8, |
| children: <Widget>[ |
| OutlinedButton( |
| style: style, |
| child: const Text('OUTLINED BUTTON', semanticsLabel: 'OUTLINED BUTTON 1'), |
| onPressed: () { |
| // Perform some action |
| }, |
| ), |
| OutlinedButton( |
| style: style, |
| onPressed: null, |
| child: const Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 5'), |
| ), |
| ], |
| ), |
| const SizedBox(height: 16), |
| OverflowBar( |
| spacing: 8, |
| children: <Widget>[ |
| OutlinedButton.icon( |
| style: style, |
| icon: const Icon(Icons.add, size: 18.0), |
| label: const Text('OUTLINED BUTTON', semanticsLabel: 'OUTLINED BUTTON 2'), |
| onPressed: () { |
| // Perform some action |
| }, |
| ), |
| OutlinedButton.icon( |
| icon: const Icon(Icons.add, size: 18.0), |
| label: const Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 6'), |
| onPressed: null, |
| ), |
| ], |
| ), |
| ], |
| ), |
| ); |
| } |
| |
| // https://en.wikipedia.org/wiki/Free_Four |
| String? dropdown1Value = 'Free'; |
| String? dropdown2Value; |
| String? dropdown3Value = 'Four'; |
| |
| Widget buildDropdownButton() { |
| return Padding( |
| padding: const EdgeInsets.all(24.0), |
| child: Column( |
| children: <Widget>[ |
| ListTile( |
| title: const Text('Simple dropdown:'), |
| trailing: DropdownButton<String>( |
| value: dropdown1Value, |
| onChanged: (String? newValue) { |
| setState(() { |
| dropdown1Value = newValue; |
| }); |
| }, |
| items: <String>['One', 'Two', 'Free', 'Four'].map<DropdownMenuItem<String>>((String value) { |
| return DropdownMenuItem<String>( |
| value: value, |
| child: Text(value), |
| ); |
| }).toList(), |
| ), |
| ), |
| const SizedBox( |
| height: 24.0, |
| ), |
| ListTile( |
| title: const Text('Dropdown with a hint:'), |
| trailing: DropdownButton<String>( |
| value: dropdown2Value, |
| hint: const Text('Choose'), |
| onChanged: (String? newValue) { |
| setState(() { |
| dropdown2Value = newValue; |
| }); |
| }, |
| items: <String>['One', 'Two', 'Free', 'Four'].map<DropdownMenuItem<String>>((String value) { |
| return DropdownMenuItem<String>( |
| value: value, |
| child: Text(value), |
| ); |
| }).toList(), |
| ), |
| ), |
| const SizedBox( |
| height: 24.0, |
| ), |
| ListTile( |
| title: const Text('Scrollable dropdown:'), |
| trailing: DropdownButton<String>( |
| value: dropdown3Value, |
| onChanged: (String? newValue) { |
| setState(() { |
| dropdown3Value = newValue; |
| }); |
| }, |
| items: <String>[ |
| 'One', 'Two', 'Free', 'Four', 'Can', 'I', 'Have', 'A', 'Little', |
| 'Bit', 'More', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', |
| ] |
| .map<DropdownMenuItem<String>>((String value) { |
| return DropdownMenuItem<String>( |
| value: value, |
| child: Text(value), |
| ); |
| }) |
| .toList(), |
| ), |
| ), |
| ], |
| ), |
| ); |
| } |
| |
| bool iconButtonToggle = false; |
| |
| Widget buildIconButton() { |
| return Align( |
| alignment: const Alignment(0.0, -0.2), |
| child: Row( |
| mainAxisSize: MainAxisSize.min, |
| children: <Widget>[ |
| IconButton( |
| icon: const Icon( |
| Icons.thumb_up, |
| semanticLabel: 'Thumbs up', |
| ), |
| onPressed: () { |
| setState(() => iconButtonToggle = !iconButtonToggle); |
| }, |
| color: iconButtonToggle ? Theme.of(context).primaryColor : null, |
| ), |
| const IconButton( |
| icon: Icon( |
| Icons.thumb_up, |
| semanticLabel: 'Thumbs not up', |
| ), |
| onPressed: null, |
| ), |
| ] |
| .map<Widget>((Widget button) => SizedBox(width: 64.0, height: 64.0, child: button)) |
| .toList(), |
| ), |
| ); |
| } |
| |
| Widget buildActionButton() { |
| return Align( |
| alignment: const Alignment(0.0, -0.2), |
| child: FloatingActionButton( |
| tooltip: 'floating action button', |
| child: const Icon(Icons.add), |
| onPressed: () { |
| // Perform some action |
| }, |
| ), |
| ); |
| } |
| } |