Как растянуть изображение, чтобы оно соответствовало всему фону (100% высоты x 100% ширины) в Flutter?
У меня есть изображение, которое не соответствует соотношению сторон экрана моего устройства. Я хочу растянуть изображение так, чтобы оно полностью заполнило экран, и я не хочу обрезать какую-либо часть изображения.
CSS имеет концепцию процентов, поэтому я мог бы просто установить высоту и ширину на 100%. Но не похоже, что у Flutter такая концепция, и плохо просто кодировать высоту и ширину, поэтому я застрял.
Вот что у меня есть (я использую стек, так как у меня есть что-то на переднем плане изображения):
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,
],
);
19 ответов
Неправильный подход здесь.
Вместо этого используйте DecoratedBox. Или атрибут художественного оформления /foregroundDecoration Контейнера (который тогда использует DecoratedBox).
return new Container(
decoration: const BoxDecoration(
image: const DecorationImage(
fit: BoxFit.fill,
image: const AssetImage("images/common/toto.png"),
),
),
child: new Text("Hello"),
);
Следующее будет соответствовать изображению до 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
Внутри вашего стека, вы должны обернуть background
виджет в Positioned.fill.
return new Stack(
children: <Widget>[
new Positioned.fill(
child: background,
),
foreground,
],
);
Для меня при разработке для Интернета отлично работает следующее:
Image(
image: AssetImage('lib/images/portadaSchamann5.png'),
alignment: Alignment.center,
height: double.infinity,
width: double.infinity,
fit: BoxFit.fill,
),
Возможно, это не совсем то, что искал OP, но на этой странице я обнаружил себя после поиска проблемы, поэтому поделитесь ею со всеми, у кого есть аналогичная проблема:)
Стека
fit
свойство помогло мне удовлетворить мои потребности. В противном случае изображение внутри (OctoImage в моем случае) было дополнено и предоставлено другое
Image.fit
значения не дали никакого эффекта.
Stack(
fit: StackFit.expand,
children: [
Image(
image: provider,
fit: BoxFit.cover,
),
// other irrelevent children here
]
);
Ваш вопрос содержит первый шаг, но вам нужны ширина и высота. Вы можете получить ширину и высоту экрана. Вот небольшая правка
//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
Лучший пример для этого вопроса я нашел на этой странице: https://flutterbeads.com/set-background-image-in-flutter/
Используя BoxDecoration и DecorationImage:
Container(
constraints: BoxConstraints.expand(),
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/cat2.jpg"),
fit: BoxFit.cover),
)
Я думаю, что для вашей цели Flex может работать лучше, чем Container():
new Flex(
direction: Axis.vertical,
children: <Widget>[
Image.asset(asset.background)
],
)
Это должно работать,
Image.asset('assets/bg.jpg', подходит: BoxFit.cover,),
Ни один из приведенных выше ответов не помог мне. И поскольку нет принятого ответа, я обнаружил, что следующее расширенное изображение от горизонтального края до горизонтального края:
Container ( width: MediaQuery
.of(context)
.size
.width,
child:
Image.network(my_image_name, fit: BoxFit.fitWidth )
)
Посетите https://youtu.be/TQ32vqvMR80 ИЛИ
Например, если у родительского ограничителя высота: 200, тогда
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage('url'),
fit: BoxFit.cover,
),
),
),
Это будет работать, если вы хотите добавить подходящее фоновое изображение во Flutter:
class Myname extends StatelessWidget {
const Myname({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: SafeArea(
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/aj.jpg"),
fit: BoxFit.cover,
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
body: Column(),
),
),
),
);
}
}
Теперь вы можете добавить остальные вещи внутриColumn()
Я установил ширину и высоту контейнера на double.infinity вот так:
Container(
width: double.infinity,
height: double.infinity,
child: //your child
)
Я столкнулся с проблемами только с
FittedBox
поэтому я завернул свое изображение в
LayoutBuilder
:
LayoutBuilder(
builder: (_, constraints) => Image(
fit: BoxFit.fill,
width: constraints.maxWidth,
image: AssetImage(assets.example),
),
)
Это сработало как шарм, и я предлагаю вам попробовать.
Конечно, вы можете использовать высоту вместо ширины, это как раз то, что я использовал.
Для меня использование Image(fit: BoxFit.fill ...)
работал в ограниченном контейнере.
Попробуйте установить contentPadding
ListTile(
contentPadding: EdgeInsets.all(0.0),
...
)
Это сработало для меня
class _SplashScreenState extends State<SplashScreen> {
@override
Widget build(BuildContext context) {
return Container(
child: FittedBox(
child: Image.asset("images/my_image.png"),
fit: BoxFit.fill,
),);
}
}
Я не нашел ответа в этом посте, но нашел исправление:
Positioned(
bottom: 0,
top: 0,
child: Image.asset(
'assets/images/package_bg.png',
)),
Этот код делает изображение подходящим по высоте в стеке.