Skip to content

Conversation

@shihaohong
Copy link
Contributor

@shihaohong shihaohong commented Jun 17, 2019

Description

Implemented ToggleButtons widget. It is a horizontal set of toggle buttons, which are usually Text/Icon widgets.

Toggle buttons are designed to be configurable, meaning the actions performed by tapping a toggle button and the desired interface can be designed through defining the onPressed callback. See API doc examples for different suggestions.

toggle buttons

Related Issues

Fixes #3959
Related to #35088

Tests

I added the following tests:

  • Tests for default properties (colors, borders)
  • Tests for custom properties (colors, borders)
  • Tests for custom theme properties (colors, borders)
  • Directionality (RTL/LTR) test
  • Border draw test based on button state
  • Initial state test
  • Intrinsic height test
  • onPressed check tests

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I signed the CLA.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I updated/added relevant documentation (doc comments with ///).
  • All existing and new tests are passing.
  • The analyzer (flutter analyze --flutter-repo) does not report any problems on my PR.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Does your PR require Flutter developers to manually update their apps to accommodate your change?

  • Yes, this is a breaking change (Please read Handling breaking changes). Replace this with a link to the e-mail where you asked for input on this proposed change.
  • No, this is not a breaking change.

@shihaohong shihaohong added c: new feature Nothing broken; request for a new capability framework flutter/packages/flutter repository. See also f: labels. f: material design flutter/packages/flutter/material repository. labels Jun 17, 2019
@shihaohong shihaohong requested a review from HansMuller July 23, 2019 22:35
Copy link
Contributor

@HansMuller HansMuller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly trivial feedback; this PR is pretty close.

///
/// The list of [children] are laid out in a row. The state of each button
/// is controlled by [isSelected], which is a list of bools that determine
/// if a button is in an active, disabled, or selected state. They are both
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the isSelected list controls the disabled state (it's elements must be true or false - not null - after all).

/// match the length of the [children] list.
///
/// ## Customizing toggle buttons
/// The toggle buttons are designed to be configurable, meaning the actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe too many words for not enough content. I assume that what you're trying to say is that each toggle's behavior is defined by its [onPressed] callback which can update the [isSelected] list however it wants to.

/// designed. This can be configured using the [onPressed] callback, which
/// is triggered when a button is pressed.
///
/// Here is an implementation that allows for multiple buttons to be
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice examples!

/// ],
/// onPressed: (int index) {
/// setState(() {
/// for (int currentIndex = 0; currentIndex < isSelected.length; currentIndex++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be a photon's weight clearer to call currentIndex buttonIndex.

/// ```
///
/// ## ToggleButton Borders
/// The toggle buttons, by default, have a solid, 1 dp border surrounding itself
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually say "logical pixel" or just "pixel" instead of dp.

);
} else {
return BorderSide(
color: disabledBorderColor ?? toggleButtonsTheme.disabledBorderColor ?? theme.disabledColor,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we derive the disabledColor from the color scheme? Here and below


@override
Widget build(BuildContext context) {
assert(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK


@override
Widget build(BuildContext context) {
assert(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NICE asserts


@override
double computeMaxIntrinsicHeight(double width) {
return horizontalBorderSide.width +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This expression and the similar ones below can be one liners.

Copy link
Contributor Author

@shihaohong shihaohong Jul 24, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was originally thinking that having multiple succinct lines was better than having a massive one-liner, since it might be easier to read/parse it if it were multiple lines.

Primarily driven by style guide suggestions, but let me know what you think!


/// The radii of the border's corners.
///
/// By default, the border's corners are not rounded.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't need to mention default values here.

Copy link
Contributor

@HansMuller HansMuller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! This maybe the first new widget and theme to be depend exclusively on the color scheme and to follow the state of the art theme pattern.

@willlarche
Copy link
Contributor

Thank you, @shihaohong !!!

@shihaohong shihaohong merged commit 2e43b47 into flutter:master Jul 26, 2019
johnsonmh pushed a commit to johnsonmh/flutter that referenced this pull request Jul 30, 2019
* Introduces ToggleButtons widget

* Introduces ToggleButtonsTheme inherited widget

* Introduces ThemeData.toggleButtonsTheme property
@frmatthew
Copy link

Thanks for this contribution, great widget.

Is there any way to have some control over the minimum size of the children? Specifically, when the children are just icons, I'm wondering if there's a way to square up the buttons by not having the selection buttons be as wide as they are by default.

Looking for square toggle buttons like this:
image

Thanks again!

@shihaohong
Copy link
Contributor Author

Hi @frmatthew, I created a separate issue to track your request: #39216.

@tony123S
Copy link

Where can I get the full code for this toggle button?

@shihaohong shihaohong deleted the toggle-button branch September 10, 2019 16:20
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 4, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

c: new feature Nothing broken; request for a new capability f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Toggle buttons for material widgets

9 participants