In my application I have an image that can be zoomed in or out. I want to place another widget over the image and get them both scale at the same time.
The idea is first image has a window in it. I want to place 2nd image with in the window area.
I got the image scaling working with the following code. What I don't know is how to place another widget within exact area within the 1st image.
_buildWindowImage() {
return Transform.scale(
scale: _imageScale,
alignment: Alignment.topCenter,
child: Image.asset(
'assets/images/background/window_1.png',
fit: BoxFit.contain,
),
);
}
Can someone provide some help on this.
you can do
_buildWindowImage() {
return Transform.scale(
scale: _imageScale,
alignment: Alignment.topCenter,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/images/background/window_1.png',
),
fit: BoxFit.contain,
),
),
child: Center(_put_another_widget_here),
),
);
}
}
I have an image of wheel and trying to add spin animation on it with onSwipe event.
actually what I did..
I used AnimatedBuider class but image is spinning on initially.
Here the image
AnimatedBuilder(
animation: animationController,
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/wheel.png", ),
fit: BoxFit.contain,
),
borderRadius: BorderRadius.all(Radius.circular(210.0)),
),
height: MediaQuery.of(context).size.height/2.3,
width: MediaQuery.of(context).size.width/1,
),
builder: (BuildContext context, Widget _widget) {
return new Transform.rotate(
angle: animationController.value * 6.3,
child: _widget,
);
},
),
Animation controller
#override
void initState() {
super.initState();
animationController = new AnimationController(
vsync: this,
duration: new Duration(seconds: 7),
);
animationController.repeat();
}
I found the solution from flutter_spinning_wheel package
I am asking this question after going through may SO question's.
I have tried a lot of answers. But non of them is working for me !!
Most of the questions in SO are using MaterialApp, but I am returning normal Material class bcoz I don't want Actionbar or anything like that.
What I am trying to achieve?
I am trying to make a simple Login Screen, where App icon is on the top, then Username, Password & Login Button are following the App Icon.
But alas ! App icon is not getting loaded on the AssetImage.
Below is my code
class Login extends StatelessWidget{
#override
Widget build(BuildContext context) {
return new Material(
color: Color.fromARGB(255, 0, 68, 178),
child: new Container(
margin: const EdgeInsets.all(5.0),
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
//This will have Login EditTexts....
children: <Widget>[
//Adding Logo on Login Screen....
//NOT WORKING
// new DecoratedBox(
// decoration: BoxDecoration(
// image: DecorationImage(
// image: AssetImage("assets/app_logo.jpg")
// )
// ),
// ),
//NOT WORKING
// new ImageIcon(
// new AssetImage("assests/app_logo.jpg"),
// size: 24.0,
// color: Colors.white,
// ),
//NOT WORKING
// new Container(
// decoration: new BoxDecoration(
// image: new DecorationImage(
// colorFilter: new ColorFilter.mode(
// Colors.black.withOpacity(0.6),
// BlendMode.dstATop
// ),
// image: new AssetImage("assets/applogo.jpg"),
// fit: BoxFit.contain
// )
// )
// ),
//NOT WORKING
// new Image.asset(
// 'assets/applogo.jpg',
// height: 60.0,
// fit: BoxFit.cover,
// ),
//NOT WORKING
new Directionality(
textDirection:TextDirection.ltr,
child: new Image.asset(
"assets/applogo.jpg",
height: 100.0,
width: 100.0,
fit: BoxFit.contain
)
),
//WORKING
new Text("Lets Login....", textDirection: TextDirection.ltr),
//WORKING
//Username TextField goes below....
new Directionality(
textDirection: TextDirection.ltr,
child: new TextField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Enter Username:'
),
)
),
//WORKING
//Password TextField goes below......
new Directionality(
textDirection:TextDirection.ltr,
child: new TextField(
decoration: InputDecoration(
border: InputBorder.none,
hintText:"Enter Password:"
)
)
),
//WORKING
//Login Button with Inkwell goes below....
new Directionality(
textDirection:TextDirection.ltr,
child: new InkWell(
child : new RaisedButton(
padding: const EdgeInsets.all(8.0),
textColor: Colors.white,
color: Colors.blue,
onPressed: login,
child: new Text("Login", textAlign: TextAlign.center, textDirection: TextDirection.ltr)
)
)
)
],
),//child Column closes here...
),//Container closes here.....
);//return Material closes here....
}//build closes here.....
void login(){
print("Login Pressed...");
}//login closes here....
}//Login class closes here....
Below is my pubspec.yaml
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
assets:
- assets/
- assets/app_logo.jpg
There are some typos in your code when you tried referencing the image asset such as "assets/applogo.jpg" or "assests/app_logo.jpg". Try this for example:
Image.asset(
"assets/app_logo.jpg",
height: 60.0,
fit: BoxFit.cover
),
The Flutter Container height animation starts from the middle, but I need it to start from the bottom here is my code
import 'dart:math';
import 'package:flutter/material.dart';
class CorrectWrongOverlay extends StatefulWidget {
final bool _isCorrect;
final VoidCallback _onTap;
final double percentR;
final double percentW;
CorrectWrongOverlay(
this._isCorrect, this.percentR, this.percentW, this._onTap);
#override
State createState() => CorrectWrongOverlayState();
}
class CorrectWrongOverlayState extends State<CorrectWrongOverlay>
with SingleTickerProviderStateMixin {
Animation<double> _iconAnimation;
AnimationController _iconAnimationController;
#override
void initState() {
super.initState();
_iconAnimationController = AnimationController(
duration: Duration(seconds: 3), vsync: this);
_iconAnimation = CurvedAnimation(
parent: _iconAnimationController, curve: Curves.fastOutSlowIn);
_iconAnimation.addListener(() => this.setState(() {}));
_iconAnimationController.forward();
}
#override
void dispose() {
_iconAnimationController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Material(
color: Colors.black54,
child: InkWell(
onTap: () => widget._onTap(),
child: Padding(
padding: const EdgeInsets.all(18.0),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: 80.0,
height: 200.0 * _iconAnimation.value,
color: Colors.green,
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: 80.0,
height: 200.0,
color: Colors.green,
),
)
],
),
),
),
),
);
}
}
I am trying to achieve this kind of UI with height grow animations in Flutter I want the animations to start from the bottom but it starts from the center of the container and animated it both side.
to start scale animation from certain points. You can wrap your Container with Align widget and give certain start positions with simplicty.
define your controller and animation variables;
AnimationController animationController;
Animation<double> tween;
init them in initState method;
#override
void initState() {
super.initState();
animationController = AnimationController(vsync: this, duration: Duration(milliseconds: 800));
tween = Tween<double>(begin:0,end:1).animate(CurvedAnimation(parent: animationController, curve: Curves.easeIn));
animationController.addListener(() {
setState(() {});
});
}
then in build method or where ever you add use return Widget like below;
Widget animatedContainer(){
return Align(
alignment: Alignment.topRight,// .topCenter, .topLeft, .bottomLeft, bottomCenter...etc
child: Container(
width: (size.width * tween.value).abs(),
height: (200 *tween.value).abs(),
color:Colors.red
),
);
}
You could use TweenMax for Flutter package: https://pub.dartlang.org/packages/tweenmax
Here is an example: https://github.com/mrgoonie/flutter_tweenmax/blob/master/lib/screens/animated_column_chart.dart
Click on the bottom button to animate those bars.
Cheers,
If you're animating it once and don't require advanced animation control, then you don't even need to keep track of AnimationController yourself. Just use TweenAnimationBuilder, pass to it your tween, duration and curve, and let it animate widget for you:
Widget _animatedBarWidget(Widget barWidget) => TweenAnimationBuilder<double>(
tween: Tween<double>(begin: 0.0, end: 1.0),
duration: const Duration(seconds: 3),
curve: Curves.fastOutSlowIn,
builder: (BuildContext context, double value, Widget? child) {
return Align(
alignment: Alignment.bottomCenter,
heightFactor: value,
child: child!,
);
},
child: barWidget,
);
Then, just call
_animatedBarWidget(Container(width: 80.0, height: 200.0, color:Colors.red));
I have an image that doesn't match the aspect ratio of my device's screen. I want to stretch the image so that it fully fills the screen, and I don't want to crop any part of the image.
CSS has the concept of percentages, so I could just set height and width to 100%. But it doesn't seem like Flutter has that concept, and it's bad to just hard code the height and width, so I'm stuck.
Here's what I have (I'm using a Stack since I have something in the foreground of the image):
Widget background = new Container(
height: // Not sure what to put here!
width: // Not sure what to put here!
child: new Image.asset(
asset.background,
fit: BoxFit.fill, // I thought this would fill up my Container but it doesn't
),
);
return new Stack(
children: <Widget>[
background,
foreground,
],
);
To make an Image fill its parent, simply wrap it into a FittedBox:
FittedBox(
child: Image.asset('foo.png'),
fit: BoxFit.fill,
)
FittedBox here will stretch the image to fill the space.
(Note that this functionality used to be provided by BoxFit.fill, but the API has meanwhile changed such that BoxFit no longer provides this functionality. FittedBox should work as a drop-in replacement, no changes need to be made to the constructor arguments.)
Alternatively, for complex decorations you can use a Container instead of an Image – and use decoration/foregroundDecoration fields.
To make the Container will its parent, it should either:
have no child
have alignment property not null
Here's an example that combines two images and a Text in a single Container, while taking 100% width/height of its parent:
Container(
foregroundDecoration: const BoxDecoration(
image: DecorationImage(
image: NetworkImage(
'https://p6.storage.canalblog.com/69/50/922142/85510911_o.png'),
fit: BoxFit.fill),
),
decoration: const BoxDecoration(
image: DecorationImage(
alignment: Alignment(-.2, 0),
image: NetworkImage(
'http://www.naturerights.com/blog/wp-content/uploads/2017/12/Taranaki-NR-post-1170x550.png'),
fit: BoxFit.cover),
),
alignment: Alignment.bottomCenter,
padding: EdgeInsets.only(bottom: 20),
child: Text(
"Hello World",
style: Theme.of(context)
.textTheme
.display1
.copyWith(color: Colors.white),
),
),
The following will fit the image to 100% of container width while the height is constant.
For local assets, use AssetImage
Container(
width: MediaQuery.of(context).size.width,
height: 100,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage("https://picsum.photos/250?image=9"),
),
),
)
Image fill modes:
Fill - Image is stretched
fit: BoxFit.fill
Fit Height - image kept proportional while making sure the full height of the image is shown (may overflow)
fit: BoxFit.fitHeight
Fit Width - image kept proportional while making sure the full width of the image is shown (may overflow)
fit: BoxFit.fitWidth
Cover - image kept proportional, ensures maximum coverage of the container (may overflow)
fit: BoxFit.cover
Contain - image kept proportional, minimal as possible, will reduce it's size if needed to display the entire image
fit: BoxFit.contain
Inside your Stack, you should wrap your background widget in a Positioned.fill.
return new Stack(
children: <Widget>[
new Positioned.fill(
child: background,
),
foreground,
],
);
For me, to develop for web, works fine the following:
Image(
image: AssetImage('lib/images/portadaSchamann5.png'),
alignment: Alignment.center,
height: double.infinity,
width: double.infinity,
fit: BoxFit.fill,
),
Might not be exactly what the OP was looking for, but this page is where I found myself after looking for the problem, so sharing this for everyone with similar issue :)
Stack's fit property did the trick for my needs. Otherwise Image inside (OctoImageIn my case) was padded and providing other Image.fit values did not give any effect.
Stack(
fit: StackFit.expand,
children: [
Image(
image: provider,
fit: BoxFit.cover,
),
// other irrelevent children here
]
);
Your Question contains the first step, but you need width and height. you can get the width and height of the screen. Here is a small edit
//gets the screen width and height
double Width = MediaQuery.of(context).size.width;
double Height = MediaQuery.of(context).size.height;
Widget background = new Image.asset(
asset.background,
fit: BoxFit.fill,
width: Width,
height: Height,
);
return new Stack(
children: <Widget>[
background,
foreground,
],
);
You can also use Width and Height to size other objects based on screen size.
ex: width: Height/2, height: Height/2 //using height for both keeps aspect ratio
I think that for your purpose Flex could work better than Container():
new Flex(
direction: Axis.vertical,
children: <Widget>[
Image.asset(asset.background)
],
)
The best example for this question I found on this page:
https://flutterbeads.com/set-background-image-in-flutter/
By using BoxDecoration and DecorationImage:
Container(
constraints: BoxConstraints.expand(),
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/cat2.jpg"),
fit: BoxFit.cover),
)
None of the above answers worked for me. And since there is no accepted answer, I found the following extended my image from horizontal edge to horizontal edge:
Container ( width: MediaQuery
.of(context)
.size
.width,
child:
Image.network(my_image_name, fit: BoxFit.fitWidth )
)
Visit https://youtu.be/TQ32vqvMR80
OR
For example if parent contrainer has height: 200, then
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage('url'),
fit: BoxFit.cover,
),
),
),
This should work,
Image.asset('assets/bg.jpg',fit: BoxFit.cover,),
I set width and height of a container to double.infinity like so:
Container(
width: double.infinity,
height: double.infinity,
child: //your child
)
This will work if you want to add a fit background image in Flutter:
class Myname extends StatelessWidget {
const Myname({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
home: SafeArea(
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/aj.jpg"),
fit: BoxFit.cover,
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
body: Column(),
),
),
),
);
}
}
Now you can add the rest of the things inside the Column()
For filling, I sometimes use SizedBox.expand
I ran into problems with just an FittedBox so I wrapped my Image in an LayoutBuilder:
LayoutBuilder(
builder: (_, constraints) => Image(
fit: BoxFit.fill,
width: constraints.maxWidth,
image: AssetImage(assets.example),
),
)
This worked like a charm and I suggest you give it a try.
Of course you can use height instead of width, this is just what I used.
For me, using Image(fit: BoxFit.fill ...) worked when in a bounded container.
This worked for me
class _SplashScreenState extends State<SplashScreen> {
#override
Widget build(BuildContext context) {
return Container(
child: FittedBox(
child: Image.asset("images/my_image.png"),
fit: BoxFit.fill,
),);
}
}
Try setting contentPadding
ListTile(
contentPadding: EdgeInsets.all(0.0),
...
)
I didn’t find answer in this post, But I found the fix:
Positioned(
bottom: 0,
top: 0,
child: Image.asset(
'assets/images/package_bg.png',
)),
This code make image fit to height on the stack.