I am trying to blur only a certain portion of my background in Flutter but my entire background gets blurred. I have a SizedBox in the center of my screen and i would like the background portion of where the SizedBox is laid out to be blurred out.
Here is my code:
return new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new ExactAssetImage("images/barber.jpeg"),
fit: BoxFit.cover
)
),
child: new SizedBox(
height: 200.0,
width: 200.0,
child: new BackdropFilter(
filter: new ui.ImageFilter.blur(
sigmaX: 5.0,
sigmaY: 5.0,
),
child: new Center(
child: new Text("Hi"),
),
),
),
);
}
Here is what happens instead:
I am not even sure why my text is red and has a yellow underlining. What I want is the area of the sizedBox to be blurred only.
Your SizedBox will essentially be ignored right now, because you don't tell flutter where to render it within its parent. So you need to wrap it in a center (or other alignment).
You also need to use a ClipRect to wrap your SizedBox, so that the BackdropFilter effect is clipped to that size.
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
/// This is just so that you can copy/paste this and have it run.
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
home: new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new NetworkImage(
"https://images.pexels.com/photos/668196/pexels-photo-668196.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"),
fit: BoxFit.cover)),
child: new Center(
child: new ClipRect(
child: new SizedBox(
height: 200.0,
width: 200.0,
child: new BackdropFilter(
filter: new ui.ImageFilter.blur(
sigmaX: 5.0,
sigmaY: 5.0,
),
child: new Center(
child: new Text("Hi"),
),
),
),
),
),
),
);
}
}
This is very tangential, but as to why the text is yellow and underlined, I believe that's the default if you don't specify a theme but I could be wrong about that.
to delete the yellow lines, you need to wrap the text in a Material Widget
BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 4.0,
sigmaY: 4.0,
),
child: new Center(
child: Center(
child: Material (
child: Text(" "),
color: Colors.blue.withOpacity(0.0),
)
),
),
),
Related
I am newbie in flutter and i want to show the image with full width at the top after AppBar i got the code from stack-overflow and it is working fine if i put the container inside the body of Scaffold it is showing me the image with full width along the screen but when i put this code inside the column or row it is not visible .
i have tried to show the image inside the Image() class but it doesn't adjust according to screen size. i mean it is not responsive.
import 'package:flutter/material.dart';
class SecondRoute extends StatelessWidget {
#override
Widget build(BuildContext context) {
MediaQueryData queryData;
queryData = MediaQuery.of(context);
return Scaffold(
appBar: AppBar(),
body: Container(
margin: EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
bannerImage(),
],
)
],
),
),
);
}
}
class bannerImage extends StatelessWidget {
#override
Widget build(BuildContext context) {
// TODO: implement build
return new DecoratedBox(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage("images/banner.png"),
fit: BoxFit.fitWidth,
),
));
}
}
I created separate widget for a bannerImage. kindly suggest me how i show my image with full width of screen or how i can show container without defining the child.
Thanks
put DecoratedBox inside a container and give height and width.
Try this way:
Container(
decoration: BoxDecoration(
color: const Color(0xff7c94b6),
image: DecorationImage(
image: ExactAssetImage('images/flowers.jpeg'),
fit: BoxFit.fitWidth,
),
border: Border.all(
color: Colors.black,
width: 8.0,
),
),
)
Use this container in your Column().
First of all What you want is not clear and also you can't use queryData = MediaQuery.of(context); directly you have to wrap with MaterialApp/WidgetsApp widget.
You have to set child of DecoratedBox to show image and also need to Wrap Expanded bannerImage. below are some code from you.
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Streams Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: SecondRoute());
}
}
class SecondRoute extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(
margin: EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Expanded(child: bannerImage()),
],
)
],
),
),
);
}
}
class bannerImage extends StatelessWidget {
#override
Widget build(BuildContext context) {
// TODO: implement build
return new DecoratedBox(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new NetworkImage("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSGTVf63Vm3XgOncMVSOy0-jSxdMT8KVJIc8WiWaevuWiPGe0Pm"),
fit: BoxFit.fitWidth,
),
), child: Text('dddsfdff dfdfds dfgfdgfg fdgfdddsfdff dfdfds dfgfdgfg fdgfdddsfdff dfdfds dfgfdgfg fdgfdddsfdff dfdfds dfgfdgfg fdgfdddsfdff dfdfds dfgfdgfg fdgfdddsfdff dfdfds dfgfdgfg fdgfdddsfdff dfdfds dfgfdgfg fdgfdddsfdff dfdfds dfgfdgfg fdgf'),);
}
}
Wrapping the Image code with a Container Widget that has its height and width specified, helps Container() and Row() to have your image displayed. Rows display images when they have width (double) value specified in Container() child within them, while Container() displays when a height (double) value is specified. I simply wrapped your image in a Container() widget within the Row() children and specified width and height double values. Feel free to adjust values to suit the ratio dimensions of your actual image. Hope this guide helps you on your project.
Replace the Row() widget with the below Code:
Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
height: 50.0,
width: 100.0,
decoration: BoxDecoration(
image: bannerImage(),
),
),
],
),
Please explain what you are trying to show on the screen.
When you add a column, it will place the widgets vertically and you have added a row as the only element on the screen.
When you add row, you would want to add multiple widgets placed horizontally to each other.
I recommend you to read this article to understand the layouts properly - https://medium.com/flutter-community/flutter-layout-cheat-sheet-5363348d037e
I can't figure it out how to make this background properly sized to the rest of the screen. Anyone could point me whats wrong ??
I kinda trying to make this fit the rest screen but can;t manage to do it...
class HomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Column(
children: <Widget>[
new GradientAppBar('Milkyway Galaxy'),
new Container(
child: new Stack(
children: <Widget>[
_buildBackground(),
_buildDescription(),
],
),
),
],
);
}
Widget _buildBackground() {
return new Container(
// constraints: new BoxConstraints.expand(),
child: new Image.asset('assets/images/milkyway.gif', fit: BoxFit.cover,),
);
}
Widget _buildDescription() {
return new Container(
child: new Center(
child: new Text(milkyWayGalaxy.description),
),
);
}
}
Use BoxDecoration to apply your image as a background image of your Container. Use the Expanded widget to make sure that the Container fills the remaining space of the screen:
class HomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Column(
children: <Widget>[
new GradientAppBar('Milkyway Galaxy'),
new Expanded(
child: new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage('assets/images/milkyway.gif'),
fit: BoxFit.cover,
),
),
child: new Center(
child: new Text(milkyWayGalaxy.description),
),
),
),
],
);
}
}
If the text is longer, you may want to wrap it in a SingleChildScrollView.
I have the background of my app set like so:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new ExactAssetImage('assets/lol/aatrox.jpg'),
fit: BoxFit.cover,
),
),
child: new BackdropFilter(filter: new ImageFilter.blur(sigmaX: 600.0, sigmaY: 1000.0)),
width: 400.0,
),
);
}
}
I'm wanting to blur the DecorationImage, so I added a BackdropFilter to the Container, but I don't see any change. What am I doing wrong?
You could do something like this, by blurring the container child instead.
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new ExactAssetImage('assets/dog.png'),
fit: BoxFit.cover,
),
),
child: new BackdropFilter(
filter: new ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
child: new Container(
decoration: new BoxDecoration(color: Colors.white.withOpacity(0.0)),
),
),
),
);
}
}
Screenshot:
Using Stack:
SizedBox(
height: 200,
child: Stack(
fit: StackFit.expand,
children: [
Image.asset('chocolate_image', fit: BoxFit.cover),
ClipRRect( // Clip it cleanly.
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: Container(
color: Colors.grey.withOpacity(0.1),
alignment: Alignment.center,
child: Text('CHOCOLATE'),
),
),
),
],
),
)
Without using Stack:
Container(
height: 200,
width: double.maxFinite,
decoration: BoxDecoration(
image: DecorationImage(
image: ExactAssetImage("your_chocolage_image"),
fit: BoxFit.cover,
),
),
child: ClipRRect( // make sure we apply clip it properly
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: Container(
alignment: Alignment.center,
color: Colors.grey.withOpacity(0.1),
child: Text(
"CHOCOLATE",
style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold),
),
),
),
),
)
As I mentioned here, you should wrap your ImageFiltered widget in a ClipRRect to prevent it from flowing out the widget boundaries. Here's the code:
ClipRRect(
child: ImageFiltered(
imageFilter: ImageFilter.blur(sigmaX: 3, sigmaY: 3),
child: Image.asset('assets/flutter_image.png'),
),
),
This is the output:
ImageFiltered is the perfect widget for that . It creates a widget that applies an ImageFilter to its child.
ImageFilter is an easy way to blur or transform pixels in your app . You can import it from dart:ui
Code :
ImageFiltered(
imageFilter: ImageFilter.blur(sigmaY:5,sigmaX:5), //SigmaX and Y are just for X and Y directions
child: Image.asset('assets/image.png') //here you can use any widget you'd like to blur .
)
ImageFilter.blur() make anything blurry and
ImageFilter.matrix() lets you use any matrix for
transformation ,scaling , translating , skewing and rotating
Output :
A similar widget to ImageFiltered is BackdropFilter .
BackdropFilter lets you apply filter to everything that's painted
beneath a widget , instead of applying the filter to the widget
itself.
It's also less performant . If you can do your effect with
ImageFiltered , Use it instead of BackdropFilter.
You can learn more about ImageFiltered by watching this official video or by visiting flutter.dev
It's better if you put in ClipRRect, like this :
Container(
child: ClipRRect(
child: Stack(
children: <Widget>[
FadeInImage.assetNetwork(
placeholder: placeholder,
image: thumbnail,
fit: BoxFit.cover,
),
BackdropFilter(
child: Container(
color: Colors.black12,
),
filter: ImageFilter.blur(sigmaY: 10, sigmaX: 10),
)
],
),
),
width: double.infinity,
),
This case apply for Image (Thumbnail) list items correctly.
All the above answers are correct, I'll reply to #user123456 here since I can't comment yet.
can i make the BoxDecoration image clickeble – user123456
Just wrap the whole Container with a GestureDetector
GestureDetector(
onTap: () {...},
child: Container(
...
decoration: BoxDecoration(...),
),
);
You can use Image widget. It's very simple.
Image(
image: AssetImage("assets/images/news-media.png"),
color: Colors.black,
colorBlendMode: BlendMode.softLight,
fit: BoxFit.fill,
),
I am building my first Flutter app and I would like to create a simple layout: a background image and a translucent Material Button on top of it.
My Widget tree is pretty simple, but the InkWell / Ripple is not visible. Why do I have this behaviour ?
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Material(
child: new Stack(
children: <Widget>[
new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage("res/imgs/splashscreen_bg.png"),
fit: BoxFit.cover,
))),
new Center(
child: new FlatButton(
onPressed: () {}, child: new Text("Hello world")))
],
),
);
}
}
Without the background image, the InkWell is working.
What should I do?
Thanks
After a few researches, I have found this issue: https://github.com/flutter/flutter/issues/3782
And if I change the Widget content with this new tree, it now works:
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Stack(
children: <Widget>[
new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage("res/imgs/splashscreen_bg.png"),
fit: BoxFit.cover,
))),
new Material(
type: MaterialType.transparency,
child: new FlatButton(...),
)
],
);
}
}
There was a recent update to support this: https://github.com/flutter/flutter/pull/13900. I'm not sure if it has made its way to alpha yet, but it should solve your issue.
Is it possible to make the FloatingActionButton in the centre instead of the right side?
import 'package:flutter/material.dart';
import 'number.dart';
import 'keyboard.dart';
class ContaPage extends StatelessWidget {
#override
Widget build(BuildContext context) => new Scaffold(
body: new Column(
children: <Widget>[
new Number(),
new Keyboard(),
],
),
floatingActionButton: new FloatingActionButton(
elevation: 0.0,
child: new Icon(Icons.check),
backgroundColor: new Color(0xFFE57373),
onPressed: (){}
)
);
}
I don't know if this was added since this question was first answered, but there's now floatingActionButtonLocation property on the Scaffold class.
It would work like this in your original question:
class ContaPage extends StatelessWidget {
#override
Widget build(BuildContext context) => new Scaffold(
// ...
floatingActionButton: new FloatingActionButton(
// ...FloatingActionButton properties...
),
// Here's the new attribute:
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
Also see the documentation:
Scaffold class (search floatingActionButtonLocation): https://docs.flutter.dev/flutter/material/Scaffold-class.html
...and the FloatingActionButtonLocation class: https://docs.flutter.dev/flutter/material/FloatingActionButtonLocation-class.html
With the new flutter API you do that very easily just change the floatingActionButtonLocation property in the Scaffold to
FloatingActionButtonLocation.centerFloat
Example :
return new Scaffold(
floatingActionButton: new FloatingActionButton(
child: const Icon(Icons.add),
),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerFloat,
bottomNavigationBar: new BottomAppBar(
color: Colors.white,
child: new Row(...),
),
);
Use the Property floatingActionButtonLocation of scaffold class.
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
Full Example:
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: HomePage()
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(child: Center(child: Text('Hello World')),),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.camera, color: Colors.white, size: 29,),
backgroundColor: Colors.black,
tooltip: 'Capture Picture',
elevation: 5,
splashColor: Colors.grey,
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
}
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
Use this property with floatingActionButtonLocation property in Scaffold.
FloatingActionButton Flutter - More Details
Try wrapping it in a Center widget or use a crossAxisAlignment of CrossAxisAlignment.center on your Column.
You should pick one part of your Column to be wrapped in a Flexible that will collapse to avoid overflow, or replace some or all of it with a ListView so users can scroll to see the parts that are hidden.
You can use Container and Align widgets as below:
#override
Widget build(BuildContext context) {
return new Scaffold(
body: Center(
),
floatingActionButton: Container(
padding: EdgeInsets.only(bottom: 100.0),
child: Align(
alignment: Alignment.bottomCenter,
child: FloatingActionButton.extended(
onPressed: _getPhoneAuthResult,
icon: Icon(Icons.phone_android),
label: Text("Authenticate using Phone"),
),
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
Align(
alignment: Alignment.center,
child: Container(
child: FloatingActionButton(
hoverColor: Colors.black,
elevation: 10,
onPressed: () {},
backgroundColor: Colors.pink,
child: Icon(Icons.add,),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20.0))),
),
),
),
Here I used "Align" widget to make the FloatingActionButton center. You can see it here.
after end of the floating action button widget, you can Use floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
For Example
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
File _image;
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark(),
title: "Camera App",
home: Scaffold(
appBar: AppBar(
title: Text("Camera App"),
),
body: Center(
child: Center(
child: _image == null
? Text('No image selected.')
: Image.file(_image,
alignment: Alignment.topLeft,
),
),
),
floatingActionButton: FloatingActionButton(
elevation: 50,
hoverColor: Colors.red,
autofocus: true,
onPressed: () {
imagepicker();
},
child: Icon(Icons.camera_alt),
tooltip: 'Pick Image',
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
),
);
}
Future imagepicker() async {
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
_image = image;
});
}
}
The above examples are great, but if you want to have full control over the exact location of the floating action button, you should wrap your FloatingActionButton widget with Align widget and use Alignment(x axis, y axis) to set the exact location.
Align(
alignment: Alignment(0.0, 0.8),
//control the location by changing the numbers here to anything between 1 and -1
child: FloatingActionButton()
)
By changing the logic to use crossAxisAlignment, the mainAxisAlignment and the Flexible the FloatingActionButton were centered at the bottom of the screen
import 'package:flutter/material.dart';
import 'number.dart';
import 'keyboard.dart';
class ContaPage extends StatelessWidget {
#override
Widget build(BuildContext context) => new Scaffold(
body: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Number(),
new Keyboard(),
new Flexible(
child: new Container(
padding: new EdgeInsets.only(bottom: 16.0),
child: new FloatingActionButton(
elevation: 0.0,
child: new Icon(Icons.check),
backgroundColor: new Color(0xFFE57373),
onPressed: (){}
)
)
)
],
),
);
}
For more freedom of alignment and more than 2 FAB use Stack
Stack(
children: <Widget>[
Center(
child: Center(
child: _image == null
? Text('No image selected.')
: Image.file(_image,
alignment: Alignment.topLeft,
),
),
),
Align(
alignment: Alignment.centerLeft,
child: new FloatingActionButton(
child: const Icon(Icons.skip_previous),
onPressed: () {
}),
),
Align(
alignment: Alignment.centerRight,
child: new FloatingActionButton(
child: const Icon(Icons.skip_next),
onPressed: () {
}),
),
],
)
I modified the code, now the button is in the bottom center but I do not know if it will always stay in the bottom, regardless of the size of the screen.
import 'package:flutter/material.dart';
import 'number.dart';
import 'keyboard.dart';
class ContaPage extends StatelessWidget {
#override
Widget build(BuildContext context) => new Scaffold(
body: new Column(
children: <Widget>[
new Number(),
new Keyboard(),
new Stack(
alignment: new FractionalOffset(0.5, 1.0),
children: <Widget>[
new FloatingActionButton(
elevation: 0.0,
child: new Icon(Icons.check),
backgroundColor: new Color(0xFFE57373),
onPressed: (){}
)
],
)
],
),
);
}
Since Scaffold.floatingActionButton just asks for a Widget, you can wrap your FloatingActionButton with the standard classes for more control if the Scaffold.floatingActionButtonLocation property isn't enough (which already gives you many standard placements, that can also play nicely with your appBar or bottomNavigationBar).
Container is a classic component, but a little overkill given that it combines a variety of widgets.
As others mentioned, Align is handy when you want to position relative to the Align widget itself (which if unconstrained fills to its parent). It can take a variety of preset Alignment constants, or use the Alignment constructor to specify your own relative position, e.g. Alignment(0.0, 0.0) represents the center of the rectangle, (1,1) the bottom right corner, and (-1,-1) the upper left. However, the parent of your FAB is influenced by the Scaffold's floatingActionButtonLocation:, so one way to help take it into account is by setting it to FloatingActionButtonLocation.centerDocked, which when used with Align lets you think about positioning relative to the screen's center.
But maybe you like the basic positioning provided by floatingActionButtonLocation, but just want to shift the FAB by a known number of logical pixels, e.g. to compensate for other widgets on the screen. In that case wrapping in a Padding with the appropriate EdgeInsets should work fine.
Depending on your design simply you can use persistentFooterButtons which accepts a list of widgets as children.
just like here for an example:
persistentFooterButtons: [
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
child: Align(
alignment: Alignment.center,
child: FloatingActionButton(
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context) => InstallationPage()),);
},
child: new Icon(Icons.add, color: SysColors.ICON_COLOR, size: 34.w,),
),
),
],
)
],