Flutter: приоритет сжатия виджета
Я новичок во Flutter, и теперь пытаюсь понять, как я могу установить для макетов приоритет сжатия виджетов. Что хочу например:
у меня есть
Horizontal Stack
как
Row
, внутри него:
Некоторое пространство вроде
SizedBox
, то немного. И я хочу уменьшить пространство перед текстом, когда текст выходит за пределы собственного пространства.
os ios это разрешается приоритетом сжатия в ограничениях макета, но как я могу сделать то же самое при флаттере?
мой текущий код
Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(width: titleWidth),
Expanded(child: subline),
],
)
где
titleWidth
это пространство ширины, должно применяться, когда виджет меньше доступного размера для остальных
pinkSpace
.
subline
это виджет. в данном примере это
Text
.
но код работает только как на карточке с «Но вместо этого ...» он не уменьшает пространство перед текстовым виджетом.
3 ответа
Я не вижу вашего кода, но вы можете использовать виджет карты, может он работает
Виджеты интервалов
Во Flutter есть множество виджетов, помогающих с интервалами — внутри таких виджетов, как или
Column
которые принимают список детей.
Например:
-
Spacer
- Виджет, который заполняет пространство между другими дочерними виджетами. - - Обертывает виджет и позволяет определить
flex
значение, чтобы повлиять на то, сколько места должен занимать этот виджет по сравнению с другими виджетами в списке дочерних элементов. -
Expanded
- Если вы завернете виджет в это, вы заставите виджет заполнить оставшееся пространство. -
ConstrainedBox
- Позволяет установить minWidth, maxWidth, minHeight, maxHeight для дочернего виджета.
Пример кода
Учитывая ваше требование:
- Иметь отступ для однострочного текста
- Не иметь отступа для многострочного текста
SizedBox не подходит
SizedBox
не будет работать с многострочным текстом, так как многострочный
Text
в должен быть завернут в
Flexible
(Flutter - многострочная метка внутри строки ), и SizedBox всегда будет занимать любую ширину, которую вы установили - здесь не работает комбинация Spacer, Flexible или Expanded.
Альтернативное решение
Один из вариантов — указать
Row
с mainAxisAlignment, установленным на
MainAxisAlignment.end
и используйте BoxConstraint с MediaQuery для ширины экрана, вычтенной из minWidth, который мы хотим для текстового контейнера.
- Это фактически обратная попытка SizedBox.
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),
),
),
],
);
}
}
Затем использование виджета
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.",
)
],
),
),
],
);
}
}
Как это выглядит:
- Примечание. Для более сложных вариантов использования, когда вы вычитаете minWidth, вам может потребоваться также вычесть размер других виджетов, если макет имеет несколько столбцов, например, и, возможно, размер заполнения.
попробуй этот код, надеюсь об этом
@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)),
],
)
);
}
}