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

Posted

技术标签:

【中文标题】如何在 Flutter 中拉伸图像以适合整个背景(100% 高度 x 100% 宽度)?【英文标题】:How do I stretch an image to fit the whole background (100% height x 100% width) in Flutter? 【发布时间】:2018-01-26 11:29:53 【问题描述】:

我的图片与设备屏幕的纵横比不匹配。我想拉伸图像以使其完全填满屏幕,并且我不想裁剪图像的任何部分。

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

【问题讨论】:

【参考方案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),
  ),
),

【讨论】:

如何在此处添加淡入淡出的图像小部件?我不认为我们可以。 Ty,我有我认为更新的版本,我做到了:SizedBox.expand(child: Image.asset("assets/bg.png", fit: BoxFit.fill))我> 那么为什么 fit 参数仍然存在于各种 Image 构造函数中?如果事实上已经被 FittedBox 取代了,还有什么用呢? 对我来说,它不适用于 FittedBox。但是@Ido 使用 SizedBox.expand() 的评论确实对我有用。谢谢【参考方案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


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

fit: BoxFit.cover


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

fit: BoxFit.contain

【讨论】:

永远不要使用 MediaQuery 使小部件填充其父级。这不是你想要的 @RémiRousselet 你能解释一下原因吗(或者给我一个链接到那个原因)。谢谢。 我会选择“fit: BoxFit.cover”。谢谢。【参考方案3】:

在您的 Stack 中,您应该将您的 background 小部件包装在 Positioned.fill 中。

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

【讨论】:

感谢这个Stack 小部件覆盖,我在Flutter 中搜索这个小部件,通过使用它我可以Show Container above Image,干杯!【参考方案4】:

对我来说,为 web 开发,可以正常工作:

Image(
  image: AssetImage('lib/images/portadaSchamann5.png'),
  alignment: Alignment.center,
  height: double.infinity,
  width: double.infinity,
  fit: BoxFit.fill,
),

【讨论】:

【参考方案5】:

可能不是 OP 正在寻找的东西,但这个页面是我在寻找问题后发现自己的地方,所以分享给有类似问题的每个人:)

Stack 的fit 属性满足了我的需求。否则内部的图像(在我的情况下为 OctoImage)被填充并且提供其他 Image.fit 值没有产生任何效果。

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

【讨论】:

【参考方案6】:

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

//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

【讨论】:

fit: BoxFit.fill, on Image 是救生员,谢谢:)【参考方案7】:

我认为对于您的目的,Flex 可能比 Container() 工作得更好:

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

【讨论】:

【参考方案8】:

以上答案都不适合我。由于没有公认的答案,我发现以下将我的图像从水平边缘扩展到水平边缘:

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

【讨论】:

当您只想将图像调整为全宽而不拉伸它时,此答案有效【参考方案9】:

访问https://youtu.be/TQ32vqvMR80 或

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

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

【讨论】:

【参考方案10】:

我将容器的宽度和高度设置为 double.infinity,如下所示:

Container(
        width: double.infinity,
        height: double.infinity,
        child: //your child
)

【讨论】:

这不适用于容器的子容器,仅适用于容器。【参考方案11】:

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

【讨论】:

【参考方案12】:

我在使用 FittedBox 时遇到了问题,所以我将我的图片包装在 LayoutBuilder 中:

LayoutBuilder( 
   builder: (_, constraints) => Image(
      fit: BoxFit.fill,
      width: constraints.maxWidth,
      image: AssetImage(assets.example),
   ),
)

这就像一个魅力,我建议你试一试。当然你可以使用高度而不是宽度,这正是我使用的。

【讨论】:

【参考方案13】:

对我来说,在有界容器中使用 Image(fit: BoxFit.fill ...) 是有效的。

【讨论】:

【参考方案14】:

这对我有用

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

【讨论】:

【参考方案15】:

这应该可行,

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

【讨论】:

【参考方案16】:

尝试设置contentPadding

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

【讨论】:

【参考方案17】:

我没有在这篇文章中找到答案,但我找到了解决方法:

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

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

【讨论】:

以上是关于如何在 Flutter 中拉伸图像以适合整个背景(100% 高度 x 100% 宽度)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 中设置背景图像并将该图像适合整个卡片以用于卡片视图?

CSS - 背景图像水平拉伸并垂直重复?

如何仅使用 CSS/HTML 拉伸/收缩任何尺寸的图像以最适合正方形?

html页面比较长,body里的background图片比较短,如何设置属性使图片以拉伸方式占满页面?

如何使用 CSS 拉伸表格单元格的背景图像?

如何通过 CSS 让背景图像/图像拉伸以填充容器?