如何在 Flutter 中设置背景图片?

How do I Set Background image in Flutter?

我正在尝试为主页设置背景图片。我从屏幕开始获取图像位置并填充宽度而不是高度。 我的代码中遗漏了什么吗? flutter 有图像标准吗?图片是否根据每个 phone 的屏幕分辨率缩放?

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") 
          ]
        )
      )
    );
  }
}

我不确定我理解你的问题,但如果你想让图像填满整个屏幕,你可以使用 DecorationImage with a fit of BoxFit.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 */,
      ),
    );
  }
}

关于您的第二个问题,link 到 documentation 关于如何将分辨率相关的资产图像嵌入到您的应用中。

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

查看 问题,@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"),
        )
      ],
    )
  );
}

您可以使用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

截图:


代码:

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

通过将 Scaffold 放在 Stack 下并设置 [=15],我能够在 Scaffold(甚至是 AppBar)下方应用背景=] 在第一个 "layer" 中设置了背景图像和 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: () => {},
                  ),
                ),
              ],
            ),
          ),
        ),
      ],
    );
  }
}
decoration: BoxDecoration(
      image: DecorationImage(
        image: ExactAssetImage("images/background.png"),
        fit: BoxFit.cover
      ),
    ),

这也适用于容器。

我们可以使用 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',
        ),
      ),
    ));

输出:

body: Container(
    decoration: BoxDecoration(
      image: DecorationImage(
        image: AssetImage('images/background.png'),fit:BoxFit.cover
      )
    ),
);

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

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

您可以使用FractionallySizedBox

有时 decoratedBox 无法覆盖 full-screen 尺寸。 我们可以通过用 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,
                      ),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}



输出:

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

输出:

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

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 让背景图片充满屏幕。

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

  1. 这里我使用 SizedBox.expand() 来填充可用的 space 并为其子项(容器)传递严格的约束。
  2. BoxFit.cover 枚举缩放图像并覆盖整个屏幕
 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
            ),
          ),
        ),
      ),
    );
  }

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

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),
          ),
        ),
      ),
    );
  }
}
    @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: 
        [
          //
        ],
      ),
    )));
  }
            Image.asset(
              "assets/images/background.png",
              fit: BoxFit.cover,
              height: double.infinity,
              width: double.infinity,
              alignment: Alignment.center,
            ),

如果还是有问题,说明你的图片长宽不够完美

Stack(
   children: [
         SizedBox.expand(
              child: FittedBox(
                    fit: BoxFit.cover,
                    child: Image.asset(
                      Images.splashBackground,
                    ),
                 )
          ),
          your widgets
     ])

这对我有帮助