Flutter如何在盒子内处理固定大小的图像?

55

我刚开始接触Flutter,很喜欢它,但不太能熟练地构建布局。

我正在开发一个包含卡片列表的应用程序。 每张卡片都在一个容器内,包含一张图片(固定高度和宽度)和一段文本。

我无法正确地将图片放置在卡片内。我希望这张图片覆盖整个盒子的宽度。 谢谢。

enter image description here

这是代码:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final title = 'MyApp';

    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(
          title: Text(title),
        ),
        body: ListView(
          children: <Widget>[
              Container(
                    margin:EdgeInsets.all(8.0),
                    child: Card(
                        shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
                        child: InkWell(
                           onTap: () => print("ciao"),     
                           child: Column(
                                children: <Widget>[
                                    ClipRRect(
                                      borderRadius: BorderRadius.only(
                                        topLeft: Radius.circular(8.0),
                                        topRight: Radius.circular(8.0),
                                      ),
                                      child: Image.asset(
                                        'img/britannia.jpg',
                                        width: 300,
                                        height: 150,
                                        fit:BoxFit.fill  

                                      ),
                                    ),
                                    ListTile(
                                      title: Text('Pub 1'),
                                      subtitle: Text('Location 1'),
                                    ),
                                ],
                           ),
                        ),
                    ),
              ),
          ],
        ),
      ),
    );
  }
} 

每张卡片都有固定的大小 - 固定大小是什么? - anmol.majhail
每个容器的高度必须是(例如)150。 我想根据容器(容器包含卡片)的高度缩放图像。 我希望显示第一张图片的样子,而不管源图像的尺寸。 - Francesco Romano
你尝试过使用Expanded类吗?https://docs.flutter.io/flutter/widgets/Expanded-class.html - droidBomb
我已经更新了代码和图片。我需要将Image小部件或ClipRRect小部件包装在Expanded中吗? - Francesco Romano
如何在Flutter中将小图像适配到大容器中?请提供建议。谢谢。 - Kamlesh
12个回答

61

您需要在 Column 中添加 crossAxisAlignment: CrossAxisAlignment.stretch,,以便子元素可以占用水平空间。

工作代码:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final title = 'MyApp';

return MaterialApp(
  title: title,
  home: Scaffold(
    appBar: AppBar(
      title: Text(title),
    ),
    body: ListView(
      children: <Widget>[
        Container(
          margin:EdgeInsets.all(8.0),
          child: Card(
            shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
            child: InkWell(
              onTap: () => print("ciao"),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,  // add this
                children: <Widget>[
                  ClipRRect(
                    borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(8.0),
                      topRight: Radius.circular(8.0),
                    ),
                    child: Image.network(
                        'https://placeimg.com/640/480/any',
                       // width: 300,
                        height: 150,
                        fit:BoxFit.fill

                    ),
                  ),
                  ListTile(
                    title: Text('Pub 1'),
                    subtitle: Text('Location 1'),
                  ),
                ],
              ),
            ),
          ),
        ),
        Container(
          margin:EdgeInsets.all(8.0),
          child: Card(
            shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
            child: InkWell(
              onTap: () => print("ciao"),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  ClipRRect(
                    borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(8.0),
                      topRight: Radius.circular(8.0),
                    ),
                    child: Image.network(
                        'https://placeimg.com/640/480/any',
                        // width: 300,
                        height: 150,
                        fit:BoxFit.fill

                    ),
                  ),
                  ListTile(
                    title: Text('Pub 1'),
                    subtitle: Text('Location 1'),
                  ),
                ],
              ),
            ),
          ),
        ),
        Container(
          margin:EdgeInsets.all(8.0),
          child: Card(
            shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
            child: InkWell(
              onTap: () => print("ciao"),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  ClipRRect(
                    borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(8.0),
                      topRight: Radius.circular(8.0),
                    ),
                    child: Image.network(
                        'https://placeimg.com/640/480/any',
                        // width: 300,
                        height: 150,
                        fit:BoxFit.fill

                    ),
                  ),
                  ListTile(
                    title: Text('Pub 1'),
                    subtitle: Text('Location 1'),
                  ),
                ],
              ),
            ),
          ),
        ),
      ],
    ),
      ),
    );
  }
}

输出:

输入图像描述


如何在Flutter中将小图像适配到大容器中?请提供建议。谢谢。 - Kamlesh

27

我不知道怎么做... 但是这个方法确实可以让固定大小的图片适应容器,只需在容器中添加对齐方式。

    Container(
      height: double.infinity,
      alignment: Alignment.center, // This is needed
      child: Image.asset(
        Constants.ASSETS_IMAGES + "logo.png",
        fit: BoxFit.contain,
        width: 300,
      ),
    );

对齐方式奇妙地解决了我的问题。 - Cosmin Vacaru

23

这对我起作用了

Image.network(imageUrl, fit: BoxFit.fitWidth,),

18
将 Image 组件放在容器内,并将容器对齐方式设为居中,同时为图片指定特定的宽度和高度。

return Container(
      alignment: Alignment.center,// use aligment
      color: Color.fromRGBO(0, 96, 91, 1),
      child: Image.asset('assets/images/splash_logo.png',
        height: 150,
        width: 150,
      fit: BoxFit.cover),
    );


谢谢,我漏掉了对齐部分。 - Anurag Sharma

9
 Image.asset(
                  'assets/images/desert.jpg',
                  height: 150,
                  width: MediaQuery.of(context).size.width,
                  fit:BoxFit.cover

              )

7
child: Container(
              alignment: Alignment.center,// use aligment
              child: Image.asset(
                'assets/images/call.png',
                height: 45,
                width: 45,
                fit: BoxFit.cover,
              ),
            ),

如果您需要带边框,请使用此选项

            Center(
          child: Container(
            margin: EdgeInsets.only(top: 75),
            width: 120,
            height: 120,
            alignment: Alignment.center,
            child: Image.asset(
              "assets/images/call.png",
              fit: BoxFit.cover,
              height: 45,
              width: 45,
            ),
            decoration: new BoxDecoration(
              color: Colors.white,
              borderRadius: new BorderRadius.all(new Radius.circular(120)),
              border: new Border.all(
                color: Colors.blue,
                width: 4.0,
              ),
            ),
          ),
        )

4
你只需要使用Image类的fit属性即可:
Image.asset(
  'your_image_asset',
  fit: BoxFit.fill, // Expands to fill parent (changes aspect ratio)
)

或者
Image.asset(
  'your_image_asset',
  fit: BoxFit.cover, // Zooms the image (maintains aspect ratio)
)

4

我使用过这个,对我来说工作得很好!

  Container(
                    width: MediaQuery.of(context).size.width,
                    height: 175,
                    decoration: BoxDecoration(
                      image: DecorationImage(
                        fit: BoxFit.cover,
                        image: NetworkImage(YOUTUBE_THUMBNAIL_PART_ONE +
                            video.key +
                            YOUTUBE_THUMBNAIL_PART_TWO),
                      ),
                    )),

4
你想做的可能是使用较大容器的尺寸。在这种情况下,你的媒体应该占据整个专用空间:
return Container(
      alignment: Alignment.center,
      height: double.infinity,
      width: double.infinity,
      child: Image.asset(
        '', //TODO fill path
        height: double.infinity,
        width: double.infinity,
        fit: BoxFit.cover,
      ),
    );

您可以使用 fit 参数进行调整:

  • BoxFit.cover 将覆盖整个容器
  • BoxFit.fitWidth 将适应宽度并可能会放置水平白边以填充空间
  • BoxFit.fitHeight 将适应高度并可能会放置垂直白边以填充空间

3

你想要适应宽度吗?那么 fitWidth 应该能解决问题,对吧? - Ferdi
但是为什么要给你的图像设置高度和宽度呢?这样你就不会得到想要的效果...你应该将高度定义为你的“card”小部件。 - Ferdi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接