如何在 Flutter 中拉伸图像以适应整个背景(100% 高度 x 100% 宽度) ?

我有一个图像,不匹配我的设备的屏幕宽高比。我想拉伸图像,使它完全填满屏幕,我不想裁剪图像的任何部分。

CSS has the concept of percentages, so I could just set height and width to 100%. But it doesn't seem like Flutter has that concept, and it's bad to just hard code the height and width, so I'm stuck.

Here's what I have (I'm using a Stack since I have something in the foreground of the image):

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,
],
);
228009 次浏览

Inside your Stack, you should wrap your background widget in a Positioned.fill.

return new Stack(
children: <Widget>[
new Positioned.fill(
child: background,
),
foreground,
],
);

要让一个图像填充它的父级,只需将它包装成一个 FittedBox:

FittedBox(
child: Image.asset('foo.png'),
fit: BoxFit.fill,
)

这里的 FittedBox将拉伸图像来填充空间。 (注意,这个功能过去是由 BoxFit.fill提供的,但是 API 同时也发生了变化,使得 BoxFit不再提供这个功能。FittedBox应该作为插入式替换,不需要对构造函数参数进行任何更改。)


或者,对于复杂的装饰,你可以使用 Container而不是 Image-并使用 decoration/foregroundDecoration字段。

要使 Container成为它的母公司,它应该:

  • 没有孩子
  • have alignment property not null

这里有一个例子,它将两张图片和一个 Text组合在一个单独的 Container中,同时采用其父代的100% 宽度/高度:

enter image description here

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),
),
),

我认为为了您的目的,弯曲可以比 Container ()更好地工作:

new Flex(
direction: Axis.vertical,
children: <Widget>[
Image.asset(asset.background)
],
)

对于填充,我有时使用 SizedBox.expend

当高度不变时,下面的图像将适合容器宽度的100% 。 For local assets, use 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
    

    enter image description here


  • 适合高度 -图像保持比例,同时确保图像的全高度显示(可能溢出)

    fit: BoxFit.fitHeight
    

    enter image description here


  • 适合宽度 -图像保持比例,同时确保图像的全宽显示(可能溢出)

    fit: BoxFit.fitWidth
    

    enter image description here


  • 盖子 -图像保持比例,确保最大的容器覆盖率(可能溢出)

    fit: BoxFit.cover
    

    enter image description here


  • 包含 -图像保持比例,尽可能最小,将减少它的大小,如果需要显示整个图像

    fit: BoxFit.contain
    

    enter image description here

试试设置 contentPadding

ListTile(
contentPadding: EdgeInsets.all(0.0),
...
)

您的问题包含第一步,但是您需要宽度和高度。你可以得到屏幕的宽度和高度。这里是一个小编辑

//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 根据屏幕大小调整其他对象的大小。

ex: width: Height/2, height: Height/2 //using height for both keeps aspect ratio

以上的答案对我来说都不管用。由于没有被接受的答案,我发现下面的图像将我的图像从水平边缘扩展到了水平边缘:

Container ( width: MediaQuery
.of(context)
.size
.width,
child:
Image.network(my_image_name, fit: BoxFit.fitWidth )
)

For me, using Image(fit: BoxFit.fill ...) worked when in a bounded container.

访问 < href = “ https://youtu.be/TQ32vqvMR80”rel = “ nofollow norefrer”> https://youtu.be/tq32vqvmr80 或者

例如,如果父容器的高度为: 200,则

Container(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage('url'),
fit: BoxFit.cover,
),
),
),

这招对我很管用

class _SplashScreenState extends State<SplashScreen> {
@override
Widget build(BuildContext context) {
return Container(
child: FittedBox(
child: Image.asset("images/my_image.png"),
fit: BoxFit.fill,
),);
}
}

Might not be exactly what the OP was looking for, but this page is where I found myself after looking for the problem, so sharing this for everyone with similar issue :)

Stack 的 fit属性满足了我的需求。否则,内部的 Image (在我的例子中是 OctoImageIn)被填充,并且提供其他 Image.fit值不会产生任何效果。

Stack(
fit: StackFit.expand,
children: [
Image(
image: provider,
fit: BoxFit.cover,
),
// other irrelevent children here
]
);

我将容器的宽度和高度设置为双倍。无穷大,如下所示:

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(
image: AssetImage('lib/images/portadaSchamann5.png'),
alignment: Alignment.center,
height: double.infinity,
width: double.infinity,
fit: BoxFit.fill,
),

这个应该可以,

Image.asset('assets/bg.jpg',fit: BoxFit.cover,),

I didn’t find answer in this post, But I found the fix:

        Positioned(
bottom: 0,
top: 0,
child: Image.asset(
'assets/images/package_bg.png',
)),

此代码使图像适合堆栈上的高度。

关于这个问题,我在这一页找到了一个最好的例子: Https://flutterbeads.com/set-background-image-in-flutter/

图片来源:

Container(
constraints: BoxConstraints.expand(),
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/cat2.jpg"),
fit: BoxFit.cover),
)

这将工作,如果你想添加一个合适的背景图片在扑动:

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()中添加其余的内容