I'm a beginner in Flutter, and now I try to understand how I can set for layouts of widget compression priority. What I want for example:
I have Horizontal Stack
like Row
, it has inside:
Some space like SizedBox
, then some Text
. And I want to reduce space before the text when the text is overflowing them self space.
os ios it resolving by compression priority in layout constraints, but how I can do the same on flutter?
my current code
Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(width: titleWidth),
Expanded(child: subline),
],
)
where titleWidth
is width space, should be applied when subline
widget smaller than rest accessible size pinkSpace
.
subline
is a widget. in the example, it is a Text
.
but the code works only like on the card with 'But instead this ...' it doesn't reduce space before text widget.
CodePudding user response:
I don't see your code but you can use card widget, may it work
CodePudding user response:
try this code, I hopefully about this
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(width: titleWidth),
Expanded(child:Card( child: subline)),
],
)
);
}
}
CodePudding user response:
Spacing widgets
Flutter have lots of widgets to help with spacing - inside widgets like Row
or Column
that take in a list of children.
F.ex:
Spacer
- A widget that fills the space between the other children widgets.Flexible
- Wraps a widget and allows you to define aflex
value to affect how much space this widget should take, compared to the other widgets in the children list.Expanded
- If you wrap a widget in this you make a widget fill up the remaining space.ConstrainedBox
- Allows setting minWidth, maxWidth, minHeight, maxHeight for the child widget.
Code example
Given your requirement:
- Have a indent for single line text
- Don't have a indent for multiline text
SizedBox is a no-go
SizedBox
won't work with multiline text, since multiline Text
in a Row
has to be wrapped in Flexible
(Flutter - multiline label inside row), and the SizedBox would always occupy whatever width you set it to - no combination of Spacer, Flexible, or Expanded seems to work here.
Alternative solution
One option is to specify a Row
with mainAxisAlignment set to MainAxisAlignment.end
and use a BoxConstraint with a MediaQuery for the screen width subtracted with the minWidth we want for the text container.
- This is effectively the reverse of the SizedBox attempt.
class IndentedText extends StatelessWidget {
const IndentedText({Key? key, required this.text, this.textMinWidth = 150}) : super(key: key);
final String text;
final double textMinWidth;
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: [
Flexible(
child: ConstrainedBox(
constraints: BoxConstraints(minWidth: MediaQuery.of(context).size.width - textMinWidth),
child: Text(text),
),
),
],
);
}
}
Then the usage of the widget
class SpacingExample extends StatelessWidget {
const SpacingExample({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Card(
child: Column(
children: const [
IndentedText(text: "text"),
IndentedText(
text:
"A vehicle is a object people use to get around more easily, etc etc make the text longer and multiline.",
)
],
),
),
],
);
}
}
How it looks:
- Note: For more complex use-cases when you subtract the minWidth - you might need to also subtract the size of other widgets if the layout if it have multiple Columns f.ex., and possibly the size of padding.