I'm a couple days into learning Flutter, and I keep running into a situation where I want to scale a collection of widgets (aka a Row
, Column
, Stack
, etc) down when the screen shrinks, akin to what Flexible()
does. Except unlike Flexible()
, I want all children to scale down when the container shrinks, not just the largest elements. Consider this example of a Column()
(green) with two children: a red child matching its parent's width, and a blue child with half the parent's width:
In the above case, if the green Column()
were to be constrained such that its width was less, you would end up with something like such:
However, what I am wanting is for each of the child elements (red/blue) to scale their width/height relative to each other, like this:
How can I accomplish this?
In the specific Column()
case I illustrated above, my workaround was to add a Row()
containing the blue widget as well as a Padding()
, both with equal flex properties, so that when the Column()
shrunk the blue element scaled correctly. I feel like this is a hack though, and wouldn't be as feasible if I had many elements with differing widths/alignments. It would be a nightmare to add one Padding()
for left/right aligned elements and two for centered ones. Is there a better way?
I'd also like to know of a similar solution for using Stack()
s. Using the Positional()
element seems to set the width/height in a way that the Stack()
crops any overflow. It'd be nice to have a Stack()
that scales all its children the same, just like if it was a single image, and similar to my Column()
example above.
CodePudding user response:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
static const String _title = 'Flutter Code Sample';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const MyStatelessWidget(),
),
);
}
}
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({super.key});
@override
Widget build(BuildContext context) {
return SizedBox.expand(
child: FractionallySizedBox(
widthFactor: 0.5,
heightFactor: 0.5,
alignment: FractionalOffset.center,
child: DecoratedBox(
decoration: BoxDecoration(
border: Border.all(
color: Colors.blue,
width: 4,
),
),
),
),
);
}
}
FractionallySizedBox Widget is a widget that sizes its child to a fraction of the total available space. To make it easy to understand how FractionallySizedBox works
CodePudding user response:
You can have a look at FractionallySizedBox class, you can specify the widthFactor and heightFactor e.g. 0.5 so that it is always half the size of the parent container.
Example:
Flexible(
child: FractionallySizedBox(
widthFactor: 0.5,
heightFactor: 0.5,
alignment: FractionalOffset.centerLeft,
child: Container(
color: Colors.blue),
),
),