Skip to content

[Proposal] Ability to allow children to flex in ToggleButtons and SegmentedButtons #139486

@andrewmumm-wk

Description

@andrewmumm-wk

Is there an existing issue for this?

Use case

Problem

  • I want the children of ToggleButtons and SegmentedButtons to be capable of flexing to the size of the parent the ToggleButton and SegmentedButton are in.

Buttons do not grow to fill the bottom sheet.
image

Alternatives

  • Build a new component from scratch that has the customizability desired.

DartPad example

import 'package:flutter/material.dart';

const Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(
        scaffoldBackgroundColor: darkBlue,
      ),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

enum Options {
  first,
  second,
  third,
}

List<Widget> children = [
  const Text('First'),
  const Text('Second'),
  const Text('Third'),
];

List<ButtonSegment<Options>> segments = [
  ButtonSegment(
    value: Options.first,
    label: children[0],
  ),
  ButtonSegment(
    value: Options.second,
    label: children[1],
  ),
  ButtonSegment(
    value: Options.third,
    label: children[2],
  ),
];

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: 500,
      height: 500,
      child: Column(
        children: [
          LayoutBuilder(
            builder: (context, constraints) {
              return Column(
                children: [
                  const Text('Toggle Button'),
                  const SizedBox(height: 10),
                  const Text('Default (no flex)'),
                  ToggleButtons(
                    direction: Axis.horizontal,
                    onPressed: (int index) => print(index),
                    isSelected: const [true, false, false],
                    children: children,
                  ),
                  const SizedBox(height: 50),
                  const Text('Preferred (flex mimmicked)'),
                  Container(
                    decoration: const BoxDecoration(
                      color: Colors.blueAccent,
                    ),
                    child: ToggleButtons(
                      direction: Axis.horizontal,
                      onPressed: (int index) => print(index),
                      isSelected: const [true, false, false],
                      constraints: BoxConstraints.expand(
                        width: (constraints.maxWidth / children.length) -
                            (children.length + 1),
                        height: 50,
                      ),
                      children: children,
                    ),
                  ),
                ],
              );
            },
          ),
          const SizedBox(height: 50),
          const Text('Segmented Button'),
          const SizedBox(height: 10),
          LayoutBuilder(
            builder: (context, constraints) {
              return Column(
                children: [
                  const Text('Default (no flex)'),
                  SegmentedButton<Options>(
                    showSelectedIcon: false,
                    selected: const <Options>{Options.first},
                    onSelectionChanged: (Set<Options> newSelection) =>
                        print(newSelection),
                    segments: segments,
                  ),
                  const SizedBox(height: 50),
                  const Text('Preferred (flex not achievable)'),
                  Container(
                    decoration: BoxDecoration(
                      color: Colors.blueAccent,
                      borderRadius: BorderRadius.circular(16),
                    ),
                    child: SegmentedButton<Options>(
                      showSelectedIcon: false,
                      selected: const <Options>{Options.first},
                      onSelectionChanged: (Set<Options> newSelection) =>
                          print(newSelection),
                      segments: segments,
                    ),
                  ),
                ],
              );
            },
          ),
        ],
      ),
    );
  }
}

Proposal

It would be ideal if a flex property could be set to allow the children of the ToggleButton and SegmentedButton to grow to the size of the parent.

It is possible to mock the above ideal scenario by setting constraints with a layout builder. This in not an ideal solution especially with the way that the constraints are set.

image

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projectc: new featureNothing broken; request for a new capabilityf: material designflutter/packages/flutter/material repository.frameworkflutter/packages/flutter repository. See also f: labels.r: fixedIssue is closed as already fixed in a newer versionteam-designOwned by Design Languages teamtriaged-designTriaged by Design Languages team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions