Add background image in flutter - flutter

I am trying to create the attached screen in Flutter. How do I add a background image and add the text at the specific location (ignore the white text box).
Thanks for your help

To add background image you have to use DecorationImage class and inside BoxDecoration.
class Home extends StatelessWidget{
#override
Widget build(BuildContext context){
return Scaffold(
body: Container(
decoration: BoxDecoration(
image: DecorationImage(image: AssetImage("assets/image1.jpg"), fit: BoxFit.cover),
),
child: Center(child: Text('Welcome To',style: TextStyle(
color: Colors.white,
fontSize: 40.0
),)),
)
);
}
}

Also make sure to create an assets directory and add your image asset(s) to it, then update your pubspec.yaml file under "flutter:" as below with:
flutter:
assets:
- assets/splash.png
Where splash.png is your image asset. Or just use:
flutter:
assets:
- assets/
if you want the whole directory. If not, you'll just render a blank container.

Try this;
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
decoration: BoxDecoration(
image: new DecorationImage(
image: new AssetImage("assets/splash.png"),
fit: BoxFit.cover
)
),
alignment: Alignment.bottomCenter,
padding: EdgeInsets.only(bottom: 150.0),
child: JumpingDotsProgressIndicator(
fontSize: 50.0,
numberOfDots: 4,
dotSpacing: 2.0,
color: Colors.white,
milliseconds: 400,
),
),
],
),
);
}
You can customize child section.

Related

How to change background image position and rotation in Flutter

I'm new in Flutter and I want to know how can I change position of background image in Flutter. I want to show background image in a corner of page and change it's position to hidden parts of image because of ovelflow.
As a frontend developer to achieve this, I think about changing position of image to absolute and set bottom and right to minus values but doing these in Flutter is in a different way.
How can I achieve this in Flutter?
class _WaterIntakeState extends State<WaterIntake> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Stack(
children: <Widget>[
Container(
color: Colors.white,
),
Container(
decoration: BoxDecoration(
image: DecorationImage(
colorFilter: ColorFilter.mode(Colors.white.withOpacity(0.5), BlendMode.dstATop),
image: AssetImage("assets/images/drink-water.png"),
fit: BoxFit.fitWidth,
)),
),
Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
title: Text('Water Intake'),
),
body: Container(
// child: const ButtonsWidget(),
),
),
],
),
);
}
}
Current Status :
What I want :
Just replace your second container with this Transform.translate widget
Transform.translate(
offset: Offset(-100.0, 200.0),
child: Transform.rotate(
angle: pi / 4,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
colorFilter: ColorFilter.mode(
Colors.white.withOpacity(0.5), BlendMode.dstATop),
image: AssetImage("assets/images/drink-water.png"),
fit: BoxFit.fitWidth,
)),
),
),
),
Also you can change the image position according to you by updating angle and offset
You might want to use both the Transform.translate and Transform.rotate to achieve this.
class _WaterIntakeState extends State<WaterIntake>
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Stack(
children: <Widget>[
Container(
color: Colors.white,
),
Transform.translate(
offset: Offset(-100.0, 200.0),
child: Transform.rotate(
angle: pi / 4,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
colorFilter: ColorFilter.mode(
Colors.white.withOpacity(0.5), BlendMode.dstATop),
image: AssetImage("assets/images/drink-water.png"),
fit: BoxFit.fitWidth,
)),
),
),
),
Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
title: Text('Water Intake'),
),
body: Container(
// child: const ButtonsWidget(),
),
),
],
),
);
}
}
Ofc you need to play with the offset.

One background image for multiple screens in flutter

On every page I do like this:
return Scaffold(
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
color: Colors.black,
image: DecorationImage(
image: AssetImage('assets/images/background.png'),
fit: BoxFit.cover,
colorFilter: new ColorFilter.mode(Colors.black.withOpacity(0.9), BlendMode.dstATop),
)
),
child:...
);
Are there anyway I only use one image for all screens in flutter?
You can define your custom widget for this..
customContainer(child){
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
color: Colors.black,
image: DecorationImage(
image: AssetImage('assets/images/background.png'),
fit: BoxFit.cover,
colorFilter: new ColorFilter.mode(Colors.black.withOpacity(0.9), BlendMode.dstATop),
)
),
child: child,
);
}
And.. wherever you need it..
return Scaffold(
body: customContainer(yourChildWidget),
);
Hope it answers your question..
AFAIK, there is no one function/widget/method/whatever with which you can set something globally. What you can probably do is to put the common code in a reusable class say MyBackground() and use it like this everywhere :
return Scaffold(
body: MyBackground(),
child:...
);
This way, you can re-use this code wherever needed and a change in one place will affect everywhere.
One way is to extract the code for the Scaffold with this background into a custom reusable widget that takes in a child widget from the individual screens like below:
class ScaffoldWithBackground extends StatelessWidget {
final Widget child;
ScaffoldWithBackground({#required this.child});
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
color: Colors.black,
image: DecorationImage(
image: AssetImage('assets/images/background.png'),
fit: BoxFit.cover,
colorFilter: new ColorFilter.mode(
Colors.black.withOpacity(0.9), BlendMode.dstATop),
)),
child: child));
}
}
And in your individual screens you use it like this:
return ScaffoldWithBackground(
child:...//Code for screen
);

Unable to change image size in dart

My image is unable to resize. Firstly I have put the background in the container widget. After that, I have put the logo image in the center widget using Image.assets. The main problem is that the size of the image is resizing according to the height and width. Currently, I am coding in the flutter framework using dart language.
I am doing coding in Android Studio.
#override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
home: new Scaffold(
body: new Stack(
children: <Widget>[
new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage("assets/imgs/home_bg.png"),
fit: BoxFit.cover,
)
),
),
new Center(
child: Image.asset("assets/imgs/home_logo.png",height: 300,width:300,),
)
],
),
),
);
No error messages are showing. Then also the image is not resizing.
body: Center(
child: SizedBox(
width: 100.0,
height: 100.0,
child: Image.network(
"https://th.thgim.com/opinion/op-ed/article22695424.ece/alternates/FREE_300/9thscience"),
),
))
You can use it like-
new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
new Expanded(child: new Image.asset(
"assets/imgs/home_logo.png",height: 300,width:300,
),
),
]
)
new Container(
height: 20.0,
width: 20.0,
decoration: BoxDecoration(
shape: BoxShape.circle, color: Colors.red),
child: Image.asset(
'assets/Like#3x.png',
)),
You can also try wrapping the Image in a Flexible located in a Column wich is wrapped in a Container with the dimensions you need

How do I make a full screen background image that can be translated without gaps

This creates a full screen background image that can be moved with margin, but it creates a blank sliver on the bottom.
Container(
margin: EdgeInsets.only(bottom: 50),
child: Container(
decoration: BoxDecoration(
color: snapshot.data.color,
image: DecorationImage(
image: AssetImage("assets/overlay.png"),
fit: BoxFit.cover,
),
),
),
),
How can I create a full screen background image that is slightly larger than the viewport and be able to move it around without any clipping or gaps?
This is an example code of how to set full background image try this
return new Container(
child: new Stack(
children: <Widget>[
new Container(
decoration: BoxDecoration(
// color: snapshot.data.color,
image: DecorationImage(
// image: AssetImage("assets/overlay.png"),
image: NetworkImage('http://www.vactualpapers.com/web/images/April-28-2016/Glitters%20in%20the%20Air%20HD%20Mobile%20Wallpaper.jpg'),
fit: BoxFit.cover,
),
),
),
new Scaffold(
appBar: new AppBar(
title: new Text('Full Background img'),
backgroundColor: const Color(0xFF121F2B),
),
backgroundColor: Colors.transparent,
body: new Center(
child: new Text('Hello How are you?',
style: new TextStyle(fontSize: 20.0, color: Colors.white),),
),
)
],
),
);

How do I Set Background image in Flutter?

I am trying to set a background image for the home page. I am getting the image place from start of the screen and filling the width but not the height.
Am I missing something in my code? Are there image standards for flutter? Do images scale based on each phone's screen resolution?
class BaseLayout extends StatelessWidget{
#override
Widget build(BuildContext context){
return Scaffold(
body: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Image.asset("assets/images/bulb.jpg")
]
)
)
);
}
}
I'm not sure I understand your question, but if you want the image to fill the entire screen you can use a 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 */,
),
);
}
}
For your second question, here is a link to the documentation on how to embed resolution-dependent asset images into your app.
If you use a Container as the body of the Scaffold, its size will be accordingly the size of its child, and usually that is not what you want when you try to add a background image to your app.
Looking at this other question, #collin-jackson was also suggesting to use Stack instead of Container as the body of the Scaffold and it definitely does what you want to achieve.
This is how my code looks like
#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"),
)
],
)
);
}
Screenshot:
Code:
#override
Widget build(BuildContext context) {
return DecoratedBox(
decoration: BoxDecoration(
image: DecorationImage(image: AssetImage("your_asset"), fit: BoxFit.cover),
),
child: Center(child: FlutterLogo(size: 300)),
);
}
You can use Stack to make the image stretch to the full screen.
Stack(
children: <Widget>
[
Positioned.fill( //
child: Image(
image: AssetImage('assets/placeholder.png'),
fit : BoxFit.fill,
),
),
...... // other children widgets of Stack
..........
.............
]
);
Note: Optionally if are using a Scaffold, you can put the Stack inside the Scaffold with or without AppBar according to your needs.
I was able to apply a background below the Scaffold (and even it's AppBar) by putting the Scaffold under a Stack and setting a Container in the first "layer" with the background image set and fit: BoxFit.cover property.
Both the Scaffold and AppBar has to have the backgroundColor set as Color.transparent and the elevation of AppBar has to be 0 (zero).
Voilà! Now you have a nice background below the whole Scaffold and 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: () => {},
),
),
],
),
),
),
],
);
}
}
We can use Container and mark its height as infinity
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',
),
),
));
Output:
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('images/background.png'),fit:BoxFit.cover
)
),
);
decoration: BoxDecoration(
image: DecorationImage(
image: ExactAssetImage("images/background.png"),
fit: BoxFit.cover
),
),
this also works inside a container.
Other answers are great. This is another way it can be done.
Here I use SizedBox.expand() to fill available space and for passing tight constraints for its children (Container).
BoxFit.cover enum to Zoom the image and cover whole screen
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
),
),
),
),
);
}
To set a background image without shrinking after adding the child, use this code.
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>[],
),
),
You can use the following code to set a background image to your app:
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
),
);
}
If your Container's child is a Column widget, you can use the crossAxisAlignment: CrossAxisAlignment.stretch to make your background image fill the screen.
I know there is a lot of answers to this question already, but this solution comes with a color gradient around the background image, I think you would like it
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),
),
),
),
);
}
}
Stack(
children: [
SizedBox.expand(
child: FittedBox(
fit: BoxFit.cover,
child: Image.asset(
Images.splashBackground,
),
)
),
your widgets
])
This Helped me
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
),
),
),
),
),
);
}
}
Output:
#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,
),
if still there is a problèm, it' seem like your image is not perfection in the heigth and width
Here is how you can achieve this. First example is with assets image and the second one is with network image.
Local image:
Container(
height: 200,
width: double.infinity,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/cat2.jpg"),
fit: BoxFit.cover),
),
child:
)
Network image:
Container(
height: 200,
width: double.infinity,
decoration: const BoxDecoration(
image: DecorationImage(
image: NetworkImage("https://picsum.photos/id/237/200/300"),
fit: BoxFit.cover),
),
child:
)
You can use FractionallySizedBox
Sometimes decoratedBox doesn't cover the full-screen size.
We can fix it by wrapping it with FractionallySizedBox Widget.
In this widget we give widthfactor and heightfactor.
The widthfactor shows the [FractionallySizedBox]widget should take _____ percentage of the app's width.
The heightfactor shows the [FractionallySizedBox]widget should take _____ percentage of the app's height.
Example : heightfactor = 0.3 means 30% of app's height. widthfactor = 0.4 means 40% of app's width.
Hence, for full screen set heightfactor = 1.0 and widthfactor = 1.0
Tip: FractionallySizedBox goes well with the stack widget. So that you can easily add buttons, avatars, texts over your background image in the stack widget whereas in rows and columns you cannot do that.
For more info check out this project's repository 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,
),
),
),
),
),
],
),
),
),
);
}
}
OutPut:
It can be done either of the following ways, based on your requirement:
Background image spanning accross the app Bar
Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
elevation: 0,
title: const Text(
"Home Page",
style: TextStyle(color: Colors.white),
),
backgroundColor: Colors.transparent,
),
body: Container(
height: double.infinity,
width: double.infinity,
decoration: const BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(
'https://wallpaperaccess.com/full/2440003.jpg'))
child: < Your Widgets go here >
),
));
Background image not spanning accross the app Bar
Scaffold(
appBar: AppBar(
elevation: 0,
title: const Text(
"Home Page",
style: TextStyle(color: Colors.black),
),
backgroundColor: Colors.transparent,
),
body: Container(
height: double.infinity,
width: double.infinity,
decoration: const BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(
'https://wallpaperaccess.com/full/2440003.jpg'))
child: < Your Widgets go here >
),
));
Extra :
To add background image only to the appBar refer this answer