Как растянуть изображение в соответствии со всем фоном (100% высота х 100%) во Флаттере?
У меня есть изображение, которое не соответствует соотношению сторон экрана моего устройства. Я хочу растянуть изображение так, чтобы оно полностью заполняло экран, и я не хочу обрезать какую-либо часть изображения.
CSS имеет понятие процента, поэтому я мог бы просто установить высоту и ширину на 100%. Но это не похоже, что у Флаттера есть эта концепция, и это плохо, чтобы просто кодировать высоту и ширину, поэтому я застрял.
Вот что у меня (я использую стек, так как у меня есть что-то на переднем плане изображения):
Widget background = new Container(
height: // Not sure what to put here!
width: // Not sure what to put here!
child: new Image.asset(
asset.background,
fit: BoxFit.fill, // I thought this would fill up my Container but it doesn't
),
);
return new Stack(
children: <Widget>[
background,
foreground,
],
);
Ответы
Ответ 1
Чтобы сделать Image заполнением его родителя, просто оберните его в FittedBox
:
FittedBox(
child: Image.asset('foo.png'),
fit: BoxFit.fill,
)
FittedBox
здесь растянет изображение, чтобы заполнить пространство.
(Обратите внимание, что эта функциональность раньше предоставлялась BoxFit.fill
, но API тем временем изменился так, что BoxFit
больше не предоставляет эту функциональность. FittedBox
должен работать в качестве замены, не нужно вносить никаких изменений в аргументы конструктора.)
В качестве альтернативы, для сложных декораций вы можете использовать Container
вместо Image
- и использовать поля decoration
/foregroundDecoration
.
Чтобы Container
стал его родителем, он должен:
- не иметь ребенка
- иметь свойство
alignment
не null
Вот пример, который объединяет два изображения и Text
в одном Container
, принимая 100% ширину/высоту его родителя:
Container(
foregroundDecoration: const BoxDecoration(
image: DecorationImage(
image: NetworkImage(
'https://p6.storage.canalblog.com/69/50/922142/85510911_o.png'),
fit: BoxFit.fill),
),
decoration: const BoxDecoration(
image: DecorationImage(
alignment: Alignment(-.2, 0),
image: NetworkImage(
'http://www.naturerights.com/blog/wp-content/uploads/2017/12/Taranaki-NR-post-1170x550.png'),
fit: BoxFit.cover),
),
alignment: Alignment.bottomCenter,
padding: EdgeInsets.only(bottom: 20),
child: Text(
"Hello World",
style: Theme.of(context)
.textTheme
.display1
.copyWith(color: Colors.white),
),
),
Ответ 2
Следующее будет соответствовать изображению до 100% ширины контейнера, в то время как высота постоянна. Для локальных активов используйте AssetImage
Container(
width: MediaQuery.of(context).size.width,
height: 100,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage("https://picsum.photos/250?image=9"),
),
),
)
Режимы заполнения изображения:
-
Заполнить - изображение растянуто
fit: BoxFit.fill
-
Подогнать высоту - изображение остается пропорциональным, при этом отображается полная высота изображения (возможно переполнение)
fit: BoxFit.fitHeight
-
Подогнать ширину - изображение остается пропорциональным, при этом отображается полная ширина изображения (возможно переполнение)
fit: BoxFit.fitWidth
-
Cover - изображение сохраняется пропорционально, обеспечивает максимальное покрытие контейнера (возможно переполнение)
fit: BoxFit.cover
-
Содержать - изображение сохраняется пропорциональным, минимально возможным, уменьшит его размер, если необходимо отобразить все изображение
fit: BoxFit.contain
Ответ 3
Внутри вашего стека вы должны обернуть свой background
виджет в Positioned.fill.
return new Stack(
children: <Widget>[
new Positioned.fill(
child: background,
),
foreground,
],
);
Ответ 4
Я думаю, что для вашей цели Flex может работать лучше, чем Container():
new Flex(
direction: Axis.vertical,
children: <Widget>[
Image.asset(asset.background)
],
)
Ответ 5
Для заполнения я иногда использую SizedBox.expand
Ответ 6
Попробуйте установить contentPadding
ListTile(
contentPadding: EdgeInsets.all(0.0),
...
)
Ответ 7
Ваш вопрос содержит первый шаг, но вам нужны ширина и высота. Вы можете получить ширину и высоту экрана. Вот небольшая правка
//gets the screen width and height
double Width = MediaQuery.of(context).size.width;
double Height = MediaQuery.of(context).size.height;
Widget background = new Image.asset(
asset.background,
fit: BoxFit.fill,
width: Width,
height: Height,
);
return new Stack(
children: <Widget>[
background,
foreground,
],
);
Вы также можете использовать ширину и высоту для определения размера других объектов в зависимости от размера экрана.
Пример: width: Height/2, height: Height/2//using height for both keeps aspect ratio