Blur background of image with it's foreground in flutter - android

I want to be able to replicate this kind of effect in flutter but can't seem to figure out how to do it.
I have tried to use the BlurryContainer package but it's not working.
So far, I have resorted to using a plain background for the background on which I have placed an image as foreground.
This is what I want to achieve:

You can create this type of UI using a stack with two copies of the image, one as the foreground which isn't blurred and another in the background with an ImageFilter.blur.
Here is an example:
Widget build(BuildContext context) {
return Stack(
children: [
Align(
alignment: Alignment.center,
child: SizedBox(
height: double.infinity,
width: double.infinity,
child: ClipRRect(
child: ImageFiltered(
imageFilter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: Image.network(
'https://images.unsplash.com/photo-1672162724304-866bd48a3d6f?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=686&q=80',
fit: BoxFit.cover,
),
),
),
),
),
Align(
alignment: Alignment.center,
child: Expanded(
child: Image.network(
'https://images.unsplash.com/photo-1672162724304-866bd48a3d6f?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=686&q=80',
fit: BoxFit.contain,
),
),
)
],
);
}
And here is the result using that unsplash image:

Related

this is my code and i want to know how to make the picture automatically boreder every phone

i want the height and width to adjust with each phone so the picture will fit right in every phone.
i am just writing more so the post would get submitted the qustion is simple
//
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
backgroundColor: Colors.red,
appBar: (AppBar(
title: Center(
child: Text('lord thunder'),
),
backgroundColor: Colors.white60,
)),
body: Center(
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: FittedBox(
child: Image.asset('images/images.jpg'),
fit: BoxFit.fill,
),
),
),
),
),
);
``
i was trying to make the picture fit the body perfectly on each phone.
You can use BoxFit.cover propertry inside DecorationImage
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("images/images.jpg"),
fit: BoxFit.cover
)
),
),

Flutter Multiple Heroes That Share The Same Tag Within A Subtree

I am trying to have a hero animation from a post view screen to a full screen post view. As far as I can see, it seems quite normal(my code) and I don't really understand why I am getting this error...
I don't have any other Hero widgets in my code, so I cannot see why I should be getting this error...
Here is the error I am getting:
There are multiple heroes that share the same tag within a subtree.
Here is my code:
Stack(
alignment: Alignment.center,
children: <Widget>[
Hero(
tag: 'test',
child: Container(
height: MediaQuery.of(context).size.width,
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Align(
alignment: Alignment.topRight,
child: Container(
decoration: BoxDecoration(
color: Colors.grey.shade400.withOpacity(0.5),
borderRadius: BorderRadius.circular(12.0),
),
width: 120,
height: 40,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 3,
itemBuilder: (BuildContext context, int index) {
return _configureEmoji(index);
},
),
),
),
),
decoration: BoxDecoration(
image: DecorationImage(
image: CachedNetworkImageProvider(widget.post.imageURL),
fit: BoxFit.cover,
),
),
),
),
],
),
Here is where I want the hero animation to go to:
class FullScreenView extends StatelessWidget {
final String imageURL;
FullScreenView({this.imageURL});
#override
Widget build(BuildContext context) {
return Scaffold(
body: Hero(
tag: 'test',
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
image: DecorationImage(
image: CachedNetworkImageProvider(imageURL),
fit: BoxFit.cover,
),
),
),
),
);
}
}
Thanks a lot and I really appreciate your help!
Plausible reason
The Hero widget doesn't know which Hero you clicked on, so it uses the next screen's Hero tag as a reference to perform a screen search that will close by looking for the Hero with that same tag. If there is more than one Hero with the same tag then an error will be returned as it is not known which Hero should do the animation.
Solution
The solution I use is to identify each Hero using as a reference the content inside it and in the navigation I insert this id (tag) in the navigation push argument and then add this id in the Hero of the target screen.
The most plausible way for your project is to use the post id as the Hero tag, that when sending the post data to the next screen already use the post id on the screen's Hero.

Stack Widget Error when using SingleChildScrollView

I have this code as profile screen which I need it to be able to fill a text like "HELLO" on this code example. But when I put a lot of text in it, the screen become overflow.
The problem is everytime I put SingleChildScrollView to avoid the overflow, I got another error instead.
Please tell me how I can fix this problem.
#override
Widget build(BuildContext context) {
return Container(
child: SafeArea(
child: FutureBuilder<Profile>(
future: dataService.getHttp(),
builder: ...
),
),
);
}
Widget _buildView(detail) {
return Stack(
alignment: Alignment.center,
children: <Widget>[
Column(
children: <Widget>[
Container(
height: 200.0,
child: Center(
child: Image.network(
'https://i.imgur.com/2F3Al82.jpg',
fit: BoxFit.cover,
height: double.infinity,
width: double.infinity,
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(0.0, 50.0, 0.0, 0.0),
),
Expanded(
child: Container(
color: Colors.white,
child: Column(
children: <Widget>[
Text('HELLO'),
]
),
)
),
],
),
Positioned(
top: 150.0,
child: Container(
height: 100.0,
width: 100.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: new DecorationImage(
fit: BoxFit.fill,
image: NetworkImage('https://i.imgur.com/2F3Al82.jpg'),
),
),
),
)
],
);
}
this is the error
You are getting this error because of the Expanded widget. SingleChildScrollView allows for infinite height and expanded will take up as much space as it can these two thing are incompatible if you remove the Expanded widget it should work. If you want some space around that container I suggest the Containers margin property.

Flutter | border radius not apply on Android

I want to find out why border radius wouldn't apply top half of the widget on Android.
Here is the image on Android
However on the web, it's working like image below.
Does anyone know why?
Code
Center(
child: Card(
elevation: 1.5,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0))),
child: SizedBox(
width: 250.0,
height: 150.0,
child: Column(
children: <Widget>[
Container(
width: double.infinity,
height: 60.0,
color: Colors.pink[200].withOpacity(0.95),
child: Center(
child: Text('Felicity Jones'),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Center(
child: Text('9:15'),
),
),
)
],
),
),
),
),
If you observe carefully by changing the opacity of the color for time being to:
color: Colors.pink[200].withOpacity(0.2),
You'll see that the top left and top right corners are cut-off and not filled by the color:
In order to avoid this, use Card widget's clipBehavior: Clip.antiAlias, property that covers all corners of the card with the given color. Here's the updated result:
Hope this answers your question.
You can try the following:
Center(
child:
Card(
elevation: 1.5,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0))),
child: SizedBox(
width: 250.0,
height: 150.0,
child: Column(
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.vertical(
top: new Radius.circular(16.0)
),
color: Colors.pink[200].withOpacity(0.95),
),
width: double.infinity,
height: 60.0,
child: Center(
child: Text('Felicity Jones'),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Center(
child: Text('9:15'),
),
),
)
],
),
),
),
),
Note that the color was moved inside the BoxDecoration as it will fail to compile otherwise.
I kept the shape attribute so that the lower part of the card will be rounded as well. You could tinker with that and remove it, if necessary.
Edit: In your case like #Darshan mentioned you can just set clipBehavior: Clip.antiAlias in Card widget.
You can use also use ClipRRect to force the child to have the given border radius, if you don't have clipBehavior.
Center(
child: Card(
elevation: 1.5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.0),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(16.0),
child: SizedBox(
width: 250.0,
height: 150.0,
child: Column(
children: <Widget>[
Container(
width: double.infinity,
height: 60.0,
color: Colors.pink[200].withOpacity(0.95),
child: Center(
child: Text('Felicity Jones'),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Center(
child: Text('9:15'),
),
),
)
],
),
),
),
),
)

How to set a BackdropFilter using dynamic-sized widgets in Flutter

I have a column: header with text, body with image, footer with text, all widgets have transparent backgrounds.
I want to set the background using a blur of the main image but I keep reaching dead ends.
In some situations this would be straight forward but in my scenario the image could be of any size and aspect ratio, and I need the effect to be wrapped with the column.
Here are my two failed attempts:
Method 1
I have a Stack with the image as the first item, then a BackdropFilter with ImageFilter blur, then my Column.
This works but the Image bleeds out from under the Column because of the image size (which can be any size).
I want to constrain it to the height of my Column.
return Container(
child: Stack(
alignment: AlignmentDirectional.topCenter,
children: <Widget>[
Positioned.fill(child: Image.network(_imgUrl)),
BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
child: Container(
decoration: BoxDecoration(color: Colors.white.withOpacity(0.0)),
)),
Container(
child: Column(
mainAxisSize: MainAxisSize.min,
// https://stackoverflow.com/a/41846093/3429021
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Header(),
BodyPhoto(),
Footer()
],
),
),
],
),
Method 2
Putting the column in a Container with a DecorationImage, which sizes the image perfectly, but I have no way of applying the blur effect.
(_streamItem is my Column wrapped in a container)
body: Container(child: _streamItem,
decoration: new BoxDecoration(image: DecorationImage(
image: NetworkImage(_streamItem.imgUrl),
fit: BoxFit.cover)
)
)
Any ideas?
I think you can consider using Positioned widget - it has width and height property. We can combine these widgets: Positioned > ClipRect > BackdropFilter. Please refer to the Gist: https://gist.github.com/anticafe/dc84cf6488d9defea437b702b13e2749#file-blur_multiple_widgets_with_dynamic_region-dart
Let take a look at this article to see more about BackdropFilter.
You can explicitly give a fix height to the container that contains the image, which will even look better.
In this example I have set three images of very different dimensions and has no problem rendering.
Refer the below code:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('So Help'),
),
body: new ListView(
children: <Widget>[
MyContainer(
imageUrl:
'https://i.dailymail.co.uk/i/pix/2017/01/16/20/332EE38400000578-4125738-image-a-132_1484600112489.jpg',
),
MyContainer(
imageUrl:
'http://static.guim.co.uk/sys-images/Guardian/Pix/pictures/2014/4/11/1397210130748/Spring-Lamb.-Image-shot-2-011.jpg',
),
MyContainer(
imageUrl:
'http://wackymania.com/image/2011/6/vertical-panoramic-photography/vertical-panoramic-photography-15.jpg',
),
],
),
);
}
}
class MyContainer extends StatelessWidget {
final String imageUrl;
MyContainer({#required this.imageUrl});
#override
Widget build(BuildContext context) {
return new Container(
height: 300.0,
child: new Stack(
children: <Widget>[
new Container(
child: Image.network(
this.imageUrl,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover,
),
),
BackdropFilter(
filter: Dui.ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
child: new Container(
color: Colors.transparent,
),
),
new Container(
height: 300.0,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
),
Padding(
padding: const EdgeInsets.all(20.0),
child: new Text(
'Header',
style: new TextStyle(color: Colors.white),
),
),
new Expanded(
child: Image.network(imageUrl),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: new Text(
'Footer',
style: new TextStyle(color: Colors.white),
),
),
],
),
)
],
),
);
}
}

Categories

Resources