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.
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 would like to have a background image with text inputs but I don't know which widget I should use to avoid the background image to shrink when my keyboard is active.
Here you can find two screen shots of the problem and my code:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
var backgroundImage = new BoxDecoration(
image: new DecorationImage(
image: new AssetImage('assets/forest.jpg'), fit: BoxFit.cover));
return new MaterialApp(
home: new Scaffold(
body: new Stack(
children: <Widget>[
new Container(
decoration: backgroundImage,
),
new TextField()
],
)));
}
}
closed keyboard
active keyboard
Put Container outside of Scaffold, and make Scaffold as a child of Container with the background image.
return Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/bg.png'),
fit: BoxFit.cover,
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
body: ListView(
children: <Widget>[
TextFormField(
decoration: InputDecoration(
hintText: "Email",
),
),
],
),
),
);
You can use the property resizeToAvoidBottomPadding from Scaffold :
Scaffold(
resizeToAvoidBottomPadding: false,
...
It's the default functionality of the flutter to keep UI above the keyboard so if you set resizeToAvoidBottomInset : false then you will lose the functionality of keeping your UI components above the keyboard
To have a background image in your application, and not to shrink it
better way is to do it like this
Container(
decoration: BoxDecoration(
color: primaryColor, // background color
image: DecorationImage(image: AssetImage(AppImages.appBg)),// background image above color
),
child: SafeArea(
child: Scaffold(
backgroundColor: Colors.transparent, //**IMPORTANT**
body: //All Ui code here//),
),
It is necessary to set Scaffold backgroundColor: Colors.transparent
otherwise, you won't be able to see your background image
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 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),
)
),
),
),
Main.dart
I want to loop the cards in the flutter.Since in Angular 2 just *ngFor works fine now in same way how can i loop it.I don't found and docs on flutter web.
you will find the output in the screen shot
Please help me to know how to loop cards or any other widgets
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return new MaterialApp(
home:new MyCard()
);
}
}
class MyCard extends StatelessWidget{
#override
Widget build(BuildContext context) {
Widget allcards;
return new Scaffold(
appBar: new AppBar(
title: new Text('My First App'),
backgroundColor:new Color(0xFF673AB7),
),
body: new Container(
child: new Column(
children: <Widget>[
new Card(
child: new Column(
children: <Widget>[
new Image.network('https://i.ytimg.com/vi/fq4N0hgOWzU/maxresdefault.jpg'),
new Padding(
padding: new EdgeInsets.all(7.0),
child: new Row(
children: <Widget>[
new Padding(
padding: new EdgeInsets.all(7.0),
child: new Icon(Icons.thumb_up),
),
new Padding(
padding: new EdgeInsets.all(7.0),
child: new Text('Like',style: new TextStyle(fontSize: 18.0),),
),
new Padding(
padding: new EdgeInsets.all(7.0),
child: new Icon(Icons.comment),
),
new Padding(
padding: new EdgeInsets.all(7.0),
child: new Text('Comments',style: new TextStyle(fontSize: 18.0)),
)
],
)
)
],
),
)
],
),
)
);
}
}`
This is my dart file
screen shot
Just like Angular2 having an iteratable to loop over is what makes any loop works.
So I did some refactoring in your code and added a the list, changed Column with a ListView and here is the result:
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return new MaterialApp(
home:new MyCard()
);
}
}
class MyCard extends StatelessWidget{
List cards = new List.generate(20, (i)=>new CustomCard());
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('My First App'),
backgroundColor:new Color(0xFF673AB7),
),
body: new Container(
child: new ListView(
children: cards,
)
)
);
}
}
class CustomCard extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Card(
child: new Column(
children: <Widget>[
new Image.network('https://i.ytimg.com/vi/fq4N0hgOWzU/maxresdefault.jpg'),
new Padding(
padding: new EdgeInsets.all(7.0),
child: new Row(
children: <Widget>[
new Padding(
padding: new EdgeInsets.all(7.0),
child: new Icon(Icons.thumb_up),
),
new Padding(
padding: new EdgeInsets.all(7.0),
child: new Text('Like',style: new TextStyle(fontSize: 18.0),),
),
new Padding(
padding: new EdgeInsets.all(7.0),
child: new Icon(Icons.comment),
),
new Padding(
padding: new EdgeInsets.all(7.0),
child: new Text('Comments',style: new TextStyle(fontSize: 18.0)),
)
],
)
)
],
),
);
}
}
In case if any one gets error with above solution please add .toList() to
List cards = new List.generate(20, (i)=>new CustomCard()).toList();
In order to avoid this error:
This class (or a class which this class inherits from) is marked as '#immutable', but one or more of its instance fields are not final:
Just put
final
At this line:
List cards = new List.generate(20, (i)=>new CustomCard());
Staying this:
final List cards = new List.generate(20, (i)=>new CustomCard());