Expanded with max width / height?

Viewed 3263

I want widgets that has certain size but shrink if available space is too small for them to fit.
Let's say available space is 100px, and each of child widgets are 10px in width.
Say parent's size got smaller to 90px due to resize.
By default, if there are 10 childs, the 10th child will not be rendered as it overflows.
In this case, I want these 10 childs to shrink in even manner so every childs become 9px in width to fit inside parent as whole.
And even if available size is bigger than 100px, they keep their size.
Wonder if there's any way I can achieve this.

        return Expanded(
            child: Row(
                children: [
                    ...List.generate(Navigation().state.length * 2, (index) => index % 2 == 0 ?  Flexible(child: _Tab(index: index ~/ 2, refresh: refresh)) : _Seperator(index: index)),
                    Expanded(child: Container(color: ColorScheme.brightness_0))
                ]
            )
        );
...
    _Tab({ required this.index, required this.refresh }) : super(
        constraints: BoxConstraints(minWidth: 120, maxWidth: 200, minHeight: 35, maxHeight: 35),
...
3 Answers

you need to change Expanded to Flexible

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(appBar: AppBar(), body: Body()),
    );
  }
}

class Body extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 80,
      color: Colors.green,
      child: Row(
        children: List.generate(10, (i) {
          return Flexible(
            child: Container(
              constraints: BoxConstraints(maxWidth: 10, maxHeight: 10),
              foregroundDecoration: BoxDecoration(border: Border.all(color: Colors.yellow, width: 1)),
            ),
          );
        }),
      ),
    );
  }
}

two cases below
when the row > 100 and row < 100 enter image description here enter image description here

optional you can add mainAxisAlignment property to Row e.g.
mainAxisAlignment: MainAxisAlignment.spaceBetween,

Try this

ConstrainedBox(
    constraints: const BoxConstraints(maxWidth: 10,maxHeigth:10),
    child: ChildWidget(...),
)

The key lies in a combination of using Flexible around each child in the column, and setting the child's max size using BoxContraints.loose()

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Make them fit',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int theHeight = 100;

  void _incrementCounter() {
    setState(() {
      theHeight += 10;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Playing with making it fit'),
      ),
      body: Container(
        color: Colors.blue,
        child: Padding(
          // Make the space we are working with have a visible outer border area
          padding: const EdgeInsets.all(8.0),
          child: Container(
            height: 400, // Fix the area we work in for the sake of the example
            child: Column(
              children: [
                Expanded(
                  child: Column(
                    children: [
                      Flexible(child: SomeBox('A')),
                      Flexible(child: SomeBox('A')),
                      Flexible(child: SomeBox('BB')),
                      Flexible(child: SomeBox('CCC')),
                      Flexible(
                        child: SomeBox('DDDD', maxHeight: 25),
                        // use a flex value to preserve ratios.
                      ),
                      Flexible(child: SomeBox('EEEEE')),
                    ],
                  ),
                ),
                Container(
                  height: theHeight.toDouble(),  // This will change to take up more space
                  color: Colors.deepPurpleAccent, // Make it stand out
                  child: Center(
                    // Child column will get Cross axis alighnment and stretch.
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: [
                        Text('Press (+) to increase the size of this area'),
                        Text('$theHeight'),
                      ],
                    ),
                  ),
                )
              ],
            ),
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

class SomeBox extends StatelessWidget {
  final String label;
  final double
      maxHeight; // Allow the parent to control the max size of each child

  const SomeBox(
    this.label, {
    Key key,
    this.maxHeight = 45,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ConstrainedBox(
      // Creates box constraints that forbid sizes larger than the given size.
      constraints: BoxConstraints.loose(Size(double.infinity, maxHeight)),
      child: Padding(
        padding: const EdgeInsets.all(2.0),
        child: Container(
          decoration: BoxDecoration(
            color: Colors.green,
            border: Border.all(
              // Make individual "child" widgets outlined
              color: Colors.red,
              width: 2,
            ),
          ),
          key: Key(label),
          child: Center(
            child: Text(
                label), // pass a child widget in stead to make this generic
          ),
        ),
      ),
    );
  }
}
Related