9

Is there any way to dynamically expand toggle buttons to parent container width without hard coding anything. I found one answer to that which uses MediaQuery of context which only works well for full screen width. I also tried to wrap the buttons in expanded widget but that throws an error

Container(
  width: 150.0, // hardcoded for testing purpose 
  child: ToggleButtons(
    constraints:
        BoxConstraints.expand(width: MediaQuery.of(context).size.width), // this doesn't work once inside container unless hard coding it
    borderRadius: BorderRadius.circular(5),
    children: [
      ShapeToggleButton(
        text: 'Option1',
      ),
      ShapeToggleButton(
        text: 'Option2',
      ),
    ],
    isSelected: [true, false],
    onPressed: (index) {},
  ),
);
LonelyWolf
  • 4,164
  • 16
  • 36
  • Try `BoxConstraints.expand()`. (Leave parameters out.) – Abion47 Feb 28 '20 at 17:47
  • 1
    Abion47 That throws an error --- BoxConstraints forces an infinite width. – LonelyWolf Feb 28 '20 at 17:50
  • i am not sure if i get you right: suppose you have one big parent container and 2 toggle buttons, so you would like then to fill entire container - one button on the left half and one on the right half? – pskink Feb 28 '20 at 18:38
  • pskink yes... basically stretch them (dynamically) so the two (or whatever is needed) buttons takes the whole width of the parent container – LonelyWolf Feb 28 '20 at 18:45
  • 4
    `child: LayoutBuilder( builder: (context, constraints) { return ToggleButtons( children: [ Container(width: constraints.maxWidth / 2 - 1.5, alignment: Alignment.center, child: Text('Option1',)), Container(width: constraints.maxWidth / 2 - 1.5, alignment: Alignment.center, child: Text('Option2',)), ], isSelected: [true, false], onPressed: (index) {}, ); } ),` - as you can see its fighting against the system, but if you are anarchist... – pskink Feb 28 '20 at 18:56
  • 1
    Thanks pskink.. I think that would work... You can place it as an answer so I can mark this as answered – LonelyWolf Feb 28 '20 at 19:27
  • 3
    notice `1.5` magic numbers above, isn't it beautiful? but most likely good enough for a "lonely wolf fighting with the rest of the world" ;-) but seriously you would need: `width: (constraints.maxWidth - (N + 1)) / N` where `N` is number of buttons, for example 2 - of course i will not post it as an answer since it is ugly workaround that is likely not to work tomorrow or one day after ... ;-) – pskink Feb 28 '20 at 19:29
  • 1
    pskink :) Yes I already modified it to my needs. I do believe that 1.5 is width of toggle buttons borders so if I don't want a border then I can remove it from there and just use width: constraints.maxWidth / N. It works I already tried that – LonelyWolf Feb 28 '20 at 19:39
  • 1
    aha ok, good to know - i used at first `constraints.maxWidth / N` too but i had error: `width overflowed by 3 pixels` or something so thats why i used that magic – pskink Feb 28 '20 at 19:43
  • 2
    Yes it is border width... Try to add to ToggleButtons parameter renderBorder: false and you don't need to use it... I have to admit that it isn't the nicest workaround but I believe that it is definitely the only one so far so you can safely put it as an answer – LonelyWolf Feb 28 '20 at 19:48
  • 1
    oh you found `renderBorder: false` so feel free to post a self answer ;-) – pskink Feb 28 '20 at 19:50
  • 1
    No.. I can't take the credit for this... I spent a lot of time figure it out and din't come with solution so the credit is all yours :) – LonelyWolf Feb 28 '20 at 19:52
  • 1
    not at all, i was only the guy who proposed an initial idea - you finished the job - the gold / fruits / beer is yours – pskink Feb 28 '20 at 19:56
  • 2
    Ohhh.. Now we are like two lowers on the phone arguing who's gonna hang up first :D I wouldn't finish it without you so the gold is yours – LonelyWolf Feb 28 '20 at 19:58

1 Answers1

21

As suggested by psink in comment above answer is to wrap it in LayoutBuilder

        Container(
              width: 150.0, // hardcoded for testing purpose
              child: LayoutBuilder(builder: (context, constraints) {
        return ToggleButtons(
          renderBorder: false,
          constraints:
              BoxConstraints.expand(width: constraints.maxWidth / 2), //number 2 is number of toggle buttons
          borderRadius: BorderRadius.circular(5),
          children: [
            Text(
              'Option1',
            ),
            Text(
              'Option2',
            ),
          ],
          isSelected: [true, false],
          onPressed: (index) {},
        );
      })))
LonelyWolf
  • 4,164
  • 16
  • 36
  • 8
    If you are rendering the border you should also substract the weight of the border * 3 (start, middle and end, assuming you only have two children) for avoiding the overflow at the right – Pablo Johnson Oct 22 '20 at 12:10