【问题标题】:How do I Set Background image in Flutter?如何在 Flutter 中设置背景图片?
【发布时间】:2017-10-26 01:37:22
【问题描述】:

我正在尝试为主页设置背景图片。我从屏幕开始获取图像位置并填充宽度而不是高度。 我的代码中是否缺少某些内容? Flutter 有图像标准吗?图片是否会根据每部手机的屏幕分辨率进行缩放?

class BaseLayout extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return new Scaffold(
      body: new Container(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            new Image.asset("assets/images/bulb.jpg") 
          ]
        )
      )
    );
  }
}

【问题讨论】:

标签: flutter dart background-image


【解决方案1】:

我不确定我是否理解您的问题,但如果您希望图像填满整个屏幕,您可以使用 DecorationImageBoxFit.cover

class BaseLayout extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return Scaffold(
      body: Container(
        decoration: BoxDecoration(
          image: DecorationImage(
            image: AssetImage("assets/images/bulb.jpg"),
            fit: BoxFit.cover,
          ),
        ),
        child: null /* add child content here */,
      ),
    );
  }
}

对于您的第二个问题,这里是指向 documentation 的链接,了解如何将依赖分辨率的资产图像嵌入到您的应用中。

【讨论】:

  • 只要你没有孩子,这个方法就有效。如果您添加一个子项,则 Container 的大小将缩小到其子项的大小。你知道如何让容器填满整个屏幕,不管它的孩子有多大?
  • @ColinJackson 图像的大小应该是多少?宽*高?
  • @HyLian 设置容器的约束属性,constraints: BoxConstraints.expand()
  • @HyLian 将width: double.infinity 添加到带有图像的容器中。
  • 如何在颤动的容器背景中重复图案类型的图像?
【解决方案2】:

如果您使用Container 作为Scaffold 的主体,它的大小将相应地与其子项的大小一致,当您尝试将背景图像添加到您的应用程序时,这通常不是您想要的。

查看this other 问题,@collin-jackson 还建议使用Stack 而不是Container 作为Scaffold 的主体,它肯定可以实现您想要实现的目标。

这就是我的代码的样子

@override
Widget build(BuildContext context) {
  return new Scaffold(
    body: new Stack(
      children: <Widget>[
        new Container(
          decoration: new BoxDecoration(
            image: new DecorationImage(image: new AssetImage("images/background.jpg"), fit: BoxFit.cover,),
          ),
        ),
        new Center(
          child: new Text("Hello background"),
        )
      ],
    )
  );
}

【讨论】:

【解决方案3】:

您可以使用Stack 将图像拉伸到全屏。

Stack(
        children: <Widget>
        [
          Positioned.fill(  //
            child: Image(
              image: AssetImage('assets/placeholder.png'),
              fit : BoxFit.fill,
           ),
          ), 
          ...... // other children widgets of Stack
          ..........
          .............
         ]
 );

注意:如果使用Scaffold,您可以根据需要将Stack 放入Scaffold 中,带或不带AppBar

【讨论】:

  • 正是我需要的,在我的情况下,我的图像在 ShaderMask 内,因此输入 image: 名称是行不通的。
【解决方案4】:

截图:


代码:

@override
Widget build(BuildContext context) {
  return DecoratedBox(
    decoration: BoxDecoration(
      image: DecorationImage(image: AssetImage("your_asset"), fit: BoxFit.cover),
    ),
    child: Center(child: FlutterLogo(size: 300)),
  );
}

【讨论】:

  • 请放一个文本框并打开键盘,然后图像会向上移动,这不是很好的解决方案。任何其他建议,请分享。
【解决方案5】:

通过将Scaffold 放在Stack 下并在带有背景图像的第一个“层”中设置Container,我能够在Scaffold 下方应用背景(甚至是AppBar)设置和fit: BoxFit.cover 属性。

ScaffoldAppBar 都必须将backgroundColor 设置为Color.transparent,并且AppBarelevation 必须为0(零)。

瞧!现在您在整个 Scaffold 和 AppBar 下方有了一个漂亮的背景! :)

import 'package:flutter/material.dart';
import 'package:mynamespace/ui/shared/colors.dart';
import 'package:mynamespace/ui/shared/textstyle.dart';
import 'package:mynamespace/ui/shared/ui_helpers.dart';
import 'package:mynamespace/ui/widgets/custom_text_form_field_widget.dart';

class SignUpView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Stack( // <-- STACK AS THE SCAFFOLD PARENT
      children: [
        Container(
          decoration: BoxDecoration(
            image: DecorationImage(
              image: AssetImage("assets/images/bg.png"), // <-- BACKGROUND IMAGE
              fit: BoxFit.cover,
            ),
          ),
        ),
        Scaffold(
          backgroundColor: Colors.transparent, // <-- SCAFFOLD WITH TRANSPARENT BG
          appBar: AppBar(
            title: Text('NEW USER'),
            backgroundColor: Colors.transparent, // <-- APPBAR WITH TRANSPARENT BG
            elevation: 0, // <-- ELEVATION ZEROED
          ),
          body: Padding(
            padding: EdgeInsets.all(spaceXS),
            child: Column(
              children: [
                CustomTextFormFieldWidget(labelText: 'Email', hintText: 'Type your Email'),
                UIHelper.verticalSpaceSM,
                SizedBox(
                  width: double.maxFinite,
                  child: RaisedButton(
                    color: regularCyan,
                    child: Text('Finish Registration', style: TextStyle(color: white)),
                    onPressed: () => {},
                  ),
                ),
              ],
            ),
          ),
        ),
      ],
    );
  }
}

【讨论】:

    【解决方案6】:
    decoration: BoxDecoration(
          image: DecorationImage(
            image: ExactAssetImage("images/background.png"),
            fit: BoxFit.cover
          ),
        ),
    

    这也适用于容器内。

    【讨论】:

      【解决方案7】:

      我们可以使用 Container 并将其高度标记为无穷大

      body: Container(
            height: double.infinity,
            width: double.infinity,
            child: FittedBox(
              fit: BoxFit.cover,
              child: Image.network(
                'https://cdn.pixabay.com/photo/2016/10/02/22/17/red-t-shirt-1710578_1280.jpg',
              ),
            ),
          ));
      

      输出:

      【讨论】:

        【解决方案8】:
        body: Container(
            decoration: BoxDecoration(
              image: DecorationImage(
                image: AssetImage('images/background.png'),fit:BoxFit.cover
              )
            ),
        );
        

        【讨论】:

        • 所提供的答案被标记为低质量帖子以供审核。以下是How do I write a good answer? 的一些指南。这个提供的答案可以从解释中受益。仅代码答案不被视为“好”答案。
        【解决方案9】:

        要设置背景图片在添加孩子后不缩小,请使用此代码。

          body: Container(
            constraints: BoxConstraints.expand(),
              decoration: BoxDecoration(
                image: DecorationImage(
                    image: AssetImage("assets/aaa.jpg"),
                fit: BoxFit.cover,
                )
              ),
        
            //You can use any widget
            child: Column(
              children: <Widget>[],
            ),
            ),
        

        【讨论】:

        • 请放一个文本框并打开键盘,然后图像会向上移动,这不是很好的解决方案。任何其他建议,请分享。
        【解决方案10】:

        你可以使用FractionallySizedBox

        有时 decoratedBox 不会覆盖全屏大小。 我们可以通过用 FractionallySizedBox Widget 包装它来修复它。 在这个小部件中,我们给出了 widthfactor 和 heightfactor。

        widthfactor 显示 [FractionallySizedBox] 小部件应占应用宽度的 _____ 百分比。

        heightfactor 显示 [FractionallySizedBox] 小部件应占应用高度的 _____ 百分比。

        示例:heightfactor = 0.3 表示应用高度的 30%。 widthfactor = 0.4 表示应用宽度的 40%。

                Hence, for full screen set heightfactor = 1.0 and widthfactor = 1.0
        

        Tip:FractionallySizedBox 与stack 小部件配合得很好。这样您就可以轻松地在堆栈小部件中的背景图像上添加按钮、头像、文本,而在行和列中您不能这样做。

        有关更多信息,请查看此项目的存储库 github repository link for this project

        class MyApp extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
              home: Scaffold(
                body: SafeArea(
                  child: Stack(
                    children: <Widget>[
                      Container(
                        child: FractionallySizedBox(
                          heightFactor: 1.0,
                          widthFactor: 1.0,
                          //for full screen set heightFactor: 1.0,widthFactor: 1.0,
                          child: DecoratedBox(
                            decoration: BoxDecoration(
                              image: DecorationImage(
                                image: AssetImage("images/1.jpg"),
                                fit: BoxFit.fill,
                              ),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            );
          }
        }
        
        
        
        

        输出:

        【讨论】:

          【解决方案11】:
          import 'package:flutter/material.dart';
          
          void main() => runApp(DestiniApp());
          
          class DestiniApp extends StatefulWidget {
            @override
            _DestiniAppState createState() => _DestiniAppState();
          }
          
          class _DestiniAppState extends State<DestiniApp> {
            @override
            Widget build(BuildContext context) {
              return MaterialApp(
                debugShowCheckedModeBanner: false,
                home: SafeArea(
                  child: Scaffold(
                    appBar: AppBar(
                      backgroundColor: Color.fromRGBO(245, 0, 87, 1),
                      title: Text(
                        "Landing Page Bankground Image",
                      ),
                    ),
                    body: Container(
                      decoration: BoxDecoration(
                        image: DecorationImage(
                            image: ExactAssetImage("images/appBack.jpg"),
                            fit: BoxFit.cover
                        ),
                      ),
                    ),
                  ),
                ),
              );
            }
          }
          
          

          输出:

          【讨论】:

            【解决方案12】:

            您可以使用以下代码为您的应用设置背景图片:

            class HomePage extends StatelessWidget {
              @override
              Widget build(BuildContext context) {
                return Scaffold(
                  body: Container(
                    decoration: BoxDecoration(
                      image: DecorationImage(
                        image: AssetImage("images/background.jpg"),
                        fit: BoxFit.cover,
                      ),
                    ),
                    // use any child here
                    child: null
                  ),
                );
              }
            

            如果您的 Container 的子组件是 Column 小部件,您可以使用 crossAxisAlignment: CrossAxisAlignment.stretch 使您的背景图片填满屏幕。

            【讨论】:

              【解决方案13】:

              其他答案很棒。这是另一种方法。

              1. 在这里,我使用SizedBox.expand() 来填充可用空间并为其子级(容器)传递严格的约束。
              2. BoxFit.cover enum 缩放图像并覆盖整个屏幕
               Widget build(BuildContext context) {
                  return Scaffold(
                    body: SizedBox.expand( // -> 01
                      child: Container(
                        decoration: BoxDecoration(
                          image: DecorationImage(
                            image: NetworkImage('https://flutter.github.io/assets-for-api-docs/assets/widgets/owl-2.jpg'),
                            fit: BoxFit.cover,    // -> 02
                          ),
                        ),
                      ),
                    ),
                  );
                }
              

              【讨论】:

              • 完美答案。
              【解决方案14】:

              我知道这个问题已经有很多答案了,但是这个解决方案在背景图像周围有一个颜色渐变,我想你会喜欢的

              import 'package:flutter/material.dart';
              
              class BackgroundImageExample extends StatelessWidget {
                const BackgroundImageExample({Key? key}) : super(key: key);
              
                @override
                Widget build(BuildContext context) {
                  return Stack(
                    children: [
                      backgroudImage(),
                      Scaffold(
                        backgroundColor: Colors.transparent,
                        body: SafeArea(
                          child: Column(
                            children: [
                              // your body content here
                            ],
                          ),
                        ),
                      ),
                    ],
                  );
                }
              
                Widget backgroudImage() {
                  return ShaderMask(
                    shaderCallback: (bounds) => LinearGradient(
                      colors: [Colors.black, Colors.black12],
                      begin: Alignment.bottomCenter,
                      end: Alignment.center,
                    ).createShader(bounds),
                    blendMode: BlendMode.darken,
                    child: Container(
                      decoration: BoxDecoration(
                        image: DecorationImage(
                          image: AssetImage('your image here'), /// change this to your  image directory 
                          fit: BoxFit.cover,
                          colorFilter: ColorFilter.mode(Colors.black45, BlendMode.darken),
                        ),
                      ),
                    ),
                  );
                }
              }
              

              【讨论】:

                【解决方案15】:
                    @override
                  Widget build(BuildContext context) {
                    return Scaffold(
                        body: SingleChildScrollView(
                            child: Container(
                      decoration: const BoxDecoration(
                        image: DecorationImage(
                            image: AssetImage('assets/bgmain.jpg'),
                            //fit: BoxFit.cover 
                            fit: BoxFit.fill),
                      ),
                      child: Column(
                        children: 
                        [
                          //
                        ],
                      ),
                    )));
                  }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2014-04-05
                  • 2017-12-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-10-30
                  • 1970-01-01
                  • 2012-04-02
                  相关资源
                  最近更新 更多