Can anyone please explain how to get this image shading effect in Flutter.
I assume you want to get the fading out background. The best way to do it is to use a Stack, with your background image at the bottom, a gradient going from your background color to transparent above it, and then your UI elements above that. Here is a working example build:
#override
Widget build(BuildContext context) {
return Material(
child: Stack(
fit: StackFit.expand,
children: [
Image.asset('assets/background.jpg', fit: BoxFit.cover,),
Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter, end: Alignment.bottomCenter,
colors: [Colors.transparent, Colors.white],
stops: [0, .4]
)
),
),
Padding(padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
children: const [
Icon(Icons.arrow_back),
Expanded(child: Center(child: Text('Steve Johnson',
style: TextStyle(fontSize: 18)
))),
Icon(Icons.remove_circle_outline_sharp)
],
),
const SizedBox(height: 32,),
Container(
height: 96, width: 96,
decoration: BoxDecoration(
border: Border.all(color: Colors.deepOrange, width: 4),
color: Colors.white,
),
child: Image.asset('assets/profile.jpg',
alignment: Alignment.topCenter,
fit: BoxFit.fitWidth,),
),
],
)
)
]
)
);
}
Related
I want to add color gradient to a card in Flutter, tried several ways with Container and decoration but can't get the entire code to work as it should.
This is the current working code, I want to replace line 3 with a gradient:
return new Card(
elevation: 5.0,
color: color.orangeAccent, //I want to replace this color with a gradient
child: Padding(
padding: new EdgeInsets.all(15.0),
child: Column(
children: <Widget>[
InkWell(
onTap: () {},
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[],
),
),
),
]
)
),
);
I played around with the advice given in this post here but cannot integrate it with my code properly.
Wrap your column with Container and use decoration with gradient color
Card(
elevation: 5.0,
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.green,
Colors.blue,
],
begin: const FractionalOffset(0.0, 0.0),
end: const FractionalOffset(1.0, 0.0),
stops: [0.0, 1.0],
tileMode: TileMode.clamp),
),
child: Padding(
padding: new EdgeInsets.all(15.0),
child: Column(children: <Widget>[
InkWell(
onTap: () {},
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[Text("Test")],
),
),
),
])),
),
),
I want to make a design like following
I build the base layout with background image. Following is the code to achieve that. Now i want to put "Grocery store" Text on top of this image and other widgets. How can i do that ?
Widget build(BuildContext context) {
return Container(
height: 190.0,
width: size.width,
margin: const EdgeInsets.symmetric(
horizontal: 16.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: Row(
children: <Widget>[
Expanded(
child: Container(
width: size.width,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(11.0),
image: DecorationImage(
image: NetworkImage(https://www.exampledomain.com/images/background.jpg),
fit: BoxFit.cover,
),
),
// child: ????
),
),
],
),
),
],
),
);}
child: Container(
width: size.width,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(11.0),
image: DecorationImage(
image: NetworkImage(https://www.exampledomain.com/images/background.jpg),
fit: BoxFit.cover,
),
),
child: Text('Grocery store'),
//padding: <-- Using to shift text position a little bit for your requirement
),
Stack/Align is your friend.
Take a look here https://api.flutter.dev/flutter/widgets/Stack-class.html
Here is a basic example (based in your code):
Widget build(BuildContext context) {
return Stack(
children: [
Align(
alignment: Alignment.center,
child: Container(
alignment: Alignment.center,
color: Colors.red,
height: 190.0,
width: size.width,
margin: const EdgeInsets.symmetric(
horizontal: 16.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: Row(
children: <Widget>[
Expanded(
child: Container(
width: size.width,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(11.0),
image: DecorationImage(
image: NetworkImage(
"http://www.exampledomain.com/images/background.jpg"),
//fit: BoxFit.cover,
),
),
),
),
],
),
),
],
),
),
),
Align(
alignment: Alignment.center,
child: Text("Grocery store"))
]
);
}
So i want to achieve this transition color with flutter
There is a container that contain Text tile with blue color () that changing to transparent. Here is what i do so far. I'm trying to use stack and LinearGradient
return Stack(
children: [
InkWell(
onTap: () {},
child: AspectRatio(
aspectRatio: 16 / 9,
child: pageData.thumbnail == ""
? ThumnailError()
: CachedNetworkImage(
imageUrl: "https://via.placeholder.com/200x100",
placeholder: (context, url) => MyLoader(),
errorWidget: (context, url, error) => ThumnailError(),
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
),
),
),
),
),
),
Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.all(10.h),
decoration: BoxDecoration(
color: Colors.white,
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: [
AppColors.primary,
Colors.transparent,
],
stops: [
0.2,
0.33
]),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
color: AppColors.primary,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextLarge(
label: "Title",
color: Colors.white,
fontWeight: FontWeight.bold,
),
Row(
children: [
TextMedium(
label: "Category",
color: Colors.white,
),
SizedBox(
width: 10.w,
),
TextMedium(
label: pageData.duration ?? "",
color: Colors.white,
)
],
),
],
),
),
),
],
);
and here is the result
So how can i achieve the first image that i put above ? thanks in advance and sorry for my english
You can try ShaderMask to achieve the desired result.
Stack(
children: [
ClipRRect(
child: ShaderMask(
shaderCallback: (Rect bounds) {
return LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.transparent,
Colors.black
]
).createShader(bounds);
},
blendMode: BlendMode.darken,
child: Container(
width: 300,
height: 250,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/someimage.jpg'),
fit: BoxFit.cover,
),
)
))
)
]
);
ShaderMask Widget
I am using a stack, where the save 60% off widget is on top of the container with white background. I am using gradient on the discount container. I want the gradient to be solid , but as you can see in the image, it is semi-transparent and we can see the white background under it.
My stack code is:
Container(
width: width * 0.38,
height: 250,
child: Stack(
children: [
Positioned(
top: 20,
child: InkWell(
onTap: () {},
child: Container(
width: width * 0.38,
height: 200,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20)),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: 35.h),
buildProductPrice(product, _intros),
buildCheckMark(product),
],
),
),
),
),
Align(
alignment: Alignment.topCenter,
child: buildDiscountText(product, _intros)),
],
),
);
buildDiscountText widget:
return Container(
height: 40,
width: 100,
alignment: Alignment.center,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.lightBlue.withOpacity(0.8),
Color(0xffCE41FD),
],
end: Alignment.centerRight,
begin: Alignment.centerLeft,
),
borderRadius: BorderRadius.circular(20)),
child: Text(
'SAVE $_rounded %',
style: _saveTextStyle,
),
);
To get solid background I could wrap buildDiscountTextWidget with Container and provide same gradient and do this 2,3 times but I don't think that is the proper way.
here is the screen shot of the widget
You just need to remove .withOpacity(0.8) from the end of Colors.lightBlue.withOpacity(0.8)
Change buildDiscountText widget as follows:
return Container(
height: 40,
width: 100,
alignment: Alignment.center,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.lightBlue, //remove opacity
Color(0xffCE41FD),
],
end: Alignment.centerRight,
begin: Alignment.centerLeft,
),
borderRadius: BorderRadius.circular(20)),
child: Text(
'SAVE $_rounded %',
style: _saveTextStyle,
),
);
I want to make first container fixed in center and second container fixed in right but i couldn't. I add mainAxisAlignment: MainAxisAlignment.spaceBetween in row line but it didn't work. Is there different properties to adjust position of widgets?
My Code:
new Container(
width: 360,
height: 502,
decoration: new BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0xffffffff),
Color(0x00caebfe)
],
stops: [0,1]
)
),
child:Column(
//crossAxisAlignment: CrossAxisAlignment.start,
children:<Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
alignment: Alignment.center,
child: Text("JULY 2017",
style: TextStyle(
fontFamily: 'Baloo',
color: Color(0xff181743),
fontSize: 20,
fontWeight: FontWeight.w400,
fontStyle: FontStyle.normal,
)
)
),
Container(
alignment: Alignment.centerLeft,
//padding: EdgeInsets.only(left:90.0),
child: Column(
children: <Widget>[
new Container(
width: 14,
height: 5,
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(10),
gradient: LinearGradient(
colors: [
Color(0xfffe1e9a),
Color(0xfffea64c)
],
stops: [0,1]
),
)
),
new Container(
//margin: EdgeInsets.only(top:3.0),
width: 23,
height: 5,
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(10),
gradient: LinearGradient(
colors: [
Color(0xfffe1e9a),
Color(0xfffea64c)
],
stops: [0,1]
)
)
)
],)
)
]
)
]
)
),
Is there different properties to adjust position of widgets?
Following what you said you wanted to achieve, as in having the text centred and the gradients all the way to the right, I've modified your code by adding an Expanded widget around the first Container in Row and removing the width of your top Container:
Container(
height: 502,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0xffffffff),
Color(0x00caebfe)
],
stops: [0,1]
)
),
child: Column(
children:<Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
child: Center(
child: Text("JULY 2017",
style: TextStyle(
fontFamily: 'Baloo',
color: Color(0xff181743),
fontSize: 20,
fontWeight: FontWeight.w400,
fontStyle: FontStyle.normal,
)
),
),
),
Column(
children: <Widget>[
new Container(
width: 14,
height: 5,
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(10),
gradient: LinearGradient(
colors: [
Color(0xfffe1e9a),
Color(0xfffea64c)
],
stops: [0,1]
),
)
),
new Container(
//margin: EdgeInsets.only(top:3.0),
width: 23,
height: 5,
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(10),
gradient: LinearGradient(
colors: [
Color(0xfffe1e9a),
Color(0xfffea64c)
],
stops: [0,1]
)
)
)
],)
]
)
]
)
),
Are you trying to make your FirstContainer placed at the very center, and your SecondContainer at the very end?
If so, you might want to use Row, and Expanded
So it would be something like this:
Row(
mainAxisSize: MainAxisSize.max,
children: [
/// Just a placeholder container to occupy 1/3 of the Row
Expanded(child: Container()),
Expanded(child: FirstContainer()),
Expanded(child: SecondContainer()),
]
)
What this does, is add a placeholder container which occupies 1/3 of the Row, and your FirstContainer will be forced to be at the center, and SecondContainer section of the Row.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: SafeArea(
child: Scaffold(
body: new Container(
width: 360,
height: 502,
decoration: new BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xffffffff), Color(0x00caebfe)],
stops: [0, 1])),
child: Stack(
children: <Widget>[
Positioned(
right: 0,
child: Container(
alignment: Alignment.center,
child: Text("JULY 2017",
style: TextStyle(
fontFamily: 'Baloo',
color: Color(0xff181743),
fontSize: 20,
fontWeight: FontWeight.w400,
fontStyle: FontStyle.normal,
))),
),
Align(
alignment: Alignment.center,
child: Container(
child: Column(
children: <Widget>[
new Container(
width: 14,
height: 5,
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(10),
gradient: LinearGradient(colors: [
Color(0xfffe1e9a),
Color(0xfffea64c)
], stops: [
0,
1
]))),
new Container(
//margin: EdgeInsets.only(top:3.0),
width: 23,
height: 5,
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(10),
gradient: LinearGradient(colors: [
Color(0xfffe1e9a),
Color(0xfffea64c)
], stops: [
0,
1
])))
],
))),
])),
),
),
);
}
Check out this method using stack it makes it simple later can later modify thank-you.