如何在 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
属性.
Scaffold
和 AppBar
都必须将 backgroundColor
设置为 Color.transparent
并且 AppBar
的 elevation
必须是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
让背景图片充满屏幕。
其他答案都很棒。这是另一种方法。
- 这里我使用
SizedBox.expand()
来填充可用的 space 并为其子项(容器)传递严格的约束。
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
])
这对我有帮助
我正在尝试为主页设置背景图片。我从屏幕开始获取图像位置并填充宽度而不是高度。 我的代码中遗漏了什么吗? 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
的主体,它的大小将相应地成为其子项的大小,通常当您尝试添加一个时,这不是您想要的您应用的背景图片。
查看 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
属性.
Scaffold
和 AppBar
都必须将 backgroundColor
设置为 Color.transparent
并且 AppBar
的 elevation
必须是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
让背景图片充满屏幕。
其他答案都很棒。这是另一种方法。
- 这里我使用
SizedBox.expand()
来填充可用的 space 并为其子项(容器)传递严格的约束。 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
])
这对我有帮助