stack children is overflowing on image - flutter

I clip to hardedge in stack even after this black container is overflowing how can i fix this if i do fit: BoxFit.fill the image get stretched. i tried wrapping the stack in a container or card and then clip to haredge that didnt work too
here is the code i tried
Stack(
children: [
Container(
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
image: DecorationImage(
image: AssetImage(widget.image), fit: BoxFit.fill),
),
),
Positioned(
left: 0,
right: 0,
bottom: 0,
child: Container(
height: 43,
width: 162,
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.35),
borderRadius: const BorderRadius.only(bottomLeft: Radius.circular(15),bottomRight: Radius.circular(15)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(widget.info,style: RecentChats.likedetails,),
Padding(
padding: const EdgeInsets.only(left: 3),
child: Container(
height: 4,
width: 4,
decoration: const BoxDecoration(
color: DatingColoCodes.blue,
shape: BoxShape.circle,
),
),
),
],
),
Text(widget.view,style: RecentChats.viewprofile,),
],
)),
)
],
);

Can't reproduce with the given snippet, it works just fine on me when I run it, maybe try to put the complete snippet?
But anyways, you can achieve the same behavior without the Stack widget, just put the Texts as a child of the Container whose hold the image.
Here is the working example, you can copy paste and run in DartPad
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: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
padding: const EdgeInsets.all(30),
child: GridView.count(
crossAxisCount: 2,
crossAxisSpacing: 20,
mainAxisSpacing: 8,
childAspectRatio: 0.8,
children: [
for (int i=0; i<20; i++)
Container(
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(20),
image: DecorationImage(
image: NetworkImage('https://source.unsplash.com/random'),
fit: BoxFit.cover,
),
),
/// For some reason, GridView / Container are stretching
/// the height, forcing it to be in full height so we gotta
/// do some hack, we put a Column, and then put the Container
/// with the texts inside the Column as well and make the height
/// as height as the item height by using `MainAxisSize.min`.
///
/// The first Column is to position the Container inside it to
/// the bottom of the item (see: `MainAxisAlignment.end`) and force
/// the width to be full width by using `CrossAxisAlignment.stretch`
///
/// Lastly, we do a `Clip.hardEdge` to prevent the text container
/// to apear sharp-squared and follow the roundness of the parent
/// container instead.
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
color: Colors.red.withOpacity(0.70),
padding: const EdgeInsets.symmetric(vertical: 8),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Hello item $i'),
Text('Washington DC'),
],
),
),
],
),
),
],
),
),
);
}
}
Sidenote: when I say "forcing it to be full height", it means adding height property will simply just not work, that is why I put a column instead.

Related

How to break a Text (placed in a Stack widget) into multiple lines in Flutter?

I want to implement the following design in Flutter, specifically the rounded rectangle with the Text placed on it.
I have used the Stack widget to position the Text at the bottom left of the Container, but the problem is that the Text goes in one line beyond the Stack boundary, instead of breaking into the second line. For simplicity sake, I have written a simpler code as following:
#override
Widget build(BuildContext context) {
return Center(
child: Stack(
children: [
Container(
width: 150,
height: 150,
color: Colors.teal.shade300,
),
const Positioned(
left: 16,
bottom: 16,
child: Text(
"A very looooooooooooooooong teeeeeeeext",
maxLines: 2,
softWrap: true,
),
),
],
),
);
}
And the result is:
So how can I break the Text into the second line (not by using \n character), in this scenario. Or, if there is another solution other than using Stack, please tell me. Thanks.
You can use align inside the container instead of using stack
#override
Widget build(BuildContext context) {
return Center(
child: Container(
width: 150,
height: 150,
color: Colors.teal.shade300,
child: const Align(
alignment: Alignment.bottomLeft,
child: Text(
"A very looooooooooooooooong teeeeeeeext",
maxLines: 2,
softWrap: true,
),
),
),
);
}
You can use GridView to implement the following design. Like this:
GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 16.0,
crossAxisSpacing: 16.0,
),
children: [
Container(
width: 150,
height: 150,
color: Colors.teal.shade300,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('title1'),
Text('21222222222222222222222222222')
],
),
),
Container(
width: 150,
height: 150,
color: Colors.teal.shade300,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('title1'),
Text('21222222222222222222222222222')
],
),
),
Container(
width: 150,
height: 150,
color: Colors.teal.shade300,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('title1'),
Text('21222222222222222222222222222')
],
),
),
Container(
width: 150,
height: 150,
color: Colors.teal.shade300,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('title1'),
Text('21222222222222222222222222222')
],
),
),
],
)
Or you can use GridView.builder.
Use Expanded Widget
#override
Widget build(BuildContext context) {
return Center(
child: Stack(
children: [
Container(
width: 150,
height: 150,
color: Colors.teal.shade300,
),
const Positioned(
left: 16,
bottom: 16,
child: Expanded(
Text(
"A very looooooooooooooooong teeeeeeeext",
maxLines: 2,
softWrapenter code here: true,
),
),
),
],
),
);
}
Use layout like this for multiple line text on stack.
Stack(
children: [
CustomPaintCurves(),
Positioned(
top: 0.0,
left: 0.0,
right: 0.0,
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset(
AppAssets.icon_button_background,
gaplessPlayback: true,
fit: BoxFit.cover,
height: 80,
width: 80),
),
const Padding(
padding: EdgeInsets.all(8.0),
child: Text(
StringManager.appName,
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
),
const Padding(
padding: EdgeInsets.all(8.0),
child: Text(StringManager.aboutUsDescription),
),
],
),
),
],
),
A sample code snippet
Stack(
children: [
//! other children in this stack
Positioned(
left: 20, //! giving it random position
bottom: 20,
width: MediaQuery.of(context).size.width * 0.80, //! so that the `Text` widget knows where it overflows
child: const Text(
"Some Very Long Text Here .......", //! the long text you want to clip
overflow: TextOverflow.ellipsis, //! type of overflow
softWrap: false,
maxLines: 3, //! max lines before clipping the text
),
),
],
);
Explanation:
Gave random positions to the text widget (bottom left) of its container. Also gave width to the 'Positioned' widget so that the 'Text' widget knows where the text actually overflows and where it needs to apply the overflow properties.
I used 'TextOverflow.ellipsis' so that the overflowed text would go into the next line, but I specified how many lines of text I want to see (i.e. 'maxLines: 3') before the rest of the text is replaced with '...'.
this problem occur because inside stack you not applied any width of Text widget (child widget), so it will not take any width,
so in your case wrap your text widget into SizeBox and applied width , it will work.
watch full code
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({
Key? key,
required this.title,
}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Stack(
children: [
Container(
width: 150,
height: 150,
color: Colors.teal.shade300,
),
const Positioned(
left: 16,
bottom: 16,
child: SizedBox(
width: 150,
child: Text(
"A very looooooooooooooooong teeeeeeeext",
maxLines: 2,
softWrap: true,
),
),
),
],
),
),
);
}
}
see the result

Flutter - Problem about Transform with Network Image and Expanded Text

I'm trying to create a simple Container includes;
A text aligned to center left (that text can include 50 characters)
A network image which is aligned to bottom right, rotated a bit, and rounded.
I've written a code like this:
import 'package:flutter/material.dart';
class MyScreen extends StatefulWidget {
static const String idScreen = "myScreen";
#override
_MyScreenState createState() => _MyScreenState();
}
class _MyScreenState extends State<MyScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("My Screen")),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: MediaQuery.of(context).size.width,
height: 100,
alignment: Alignment.bottomRight,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadiusDirectional.circular(16.0),
color: Colors.yellow),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Baby",
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
),
Transform(
child: Image.network(
"https://target.scene7.com/is/image/Target/Baby-210913-1631564062108?wid=315&hei=315&qlt=60&fmt=png",
fit: BoxFit.contain,
),
transform: Matrix4.rotationZ(-0.2),
alignment: FractionalOffset.centerRight,
),
],
),
),
),
],
),
);
}
}
But the output is:
In order to avoid white square in image, I tried to add my picture in Transform like:
Container(
width: 50,
height: 50,
decoration: const BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.contain,
image: NetworkImage(
"https://target.scene7.com/is/image/Target/Baby-210913-1631564062108?wid=315&hei=315&qlt=60&fmt=png"
)
)
)
But flutter doesn't accept it in Transform widget. How can I solve this?
Also another problem; if I write "Baby" like "Baby Baby Baby Baby Baby Baby Baby Baby ", it gives overflow error. I tried to wrap my Text or Row with Expanded but didn't work. How can I solve this too?

Flutter: How to add BackdropFilter to SliverAppBar

I want to add a BackdropFilter() to a SliverAppbar().
I want it to look something like the iOS App Library App Bar: https://cln.sh/eP8wfY.
Header sliver not floating over the list in a NestedScrollView does so but only to the header, I want the title and the actions to be visible while the background is blurred.
Thanks!
Edit
What the pages look like: https://cln.sh/vcCY4j.
Github Gist with my code: https://gist.github.com/HadyMash/21e7bd2f7e202de02837505e1c7363e9.
NOTE: getting hard time on color, even after spending hours of time.
you need to change colors
of you find some area problem that maybe because of safeArea or CupertinoNavBar.
you can remove/change color on shadow, i'm giving too much on test purpose.
All you have to play with Colors and LinearGradient
OutPut
Here is my concept:
Stack
- backgroundImage
- Container with white.3
- CustomScrollView
- SliverToBoxAdapter 2x kToolbarHeight for extra height for GridList,
- SliverGrid
- LinearGradient 2xkToolbarHeight for fadeEffect on upper scroll
- our widget TextField or anything
Demo
class Body extends StatelessWidget {
const Body({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Scaffold(
body: LayoutBuilder(
builder: (context, constraints) => Stack(
children: [
Container(
decoration: BoxDecoration(
// color: Colors.white.withOpacity(.3),
image: DecorationImage(
image: AssetImage("assets/me.jpg"),
fit: BoxFit.cover,
),
),
child: Container(),
),
Container(
decoration: BoxDecoration(
color: Colors.white.withOpacity(.3),
),
child: CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: SizedBox(
height: kToolbarHeight * 2,
),
),
SliverPadding(
padding: EdgeInsets.all(20),
sliver: SliverGrid.count(
crossAxisCount: 2,
mainAxisSpacing: 20,
crossAxisSpacing: 20,
children: [
...List.generate(
12,
(index) => Container(
decoration: BoxDecoration(
color: index % 3 == 0
? Colors.deepPurple
: index % 3 == 1
? Colors.deepOrange
: Colors.amberAccent,
borderRadius: BorderRadius.circular(12),
),
))
],
),
)
],
),
),
Align(
alignment: Alignment.topCenter,
child: Container(
height: kToolbarHeight * 2,
width: constraints.maxWidth,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.grey,
Colors.white.withOpacity(.7),
],
),
),
child: Text(""),
),
),
Positioned(
top: kTextTabBarHeight * 1.122,
/// need to tweek
left: 20,
right: 20,
child: Container(
height: kToolbarHeight,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: Colors.white70,
boxShadow: [
BoxShadow(
blurRadius: 12,
spreadRadius: 6,
color: Colors.black54,
offset: Offset(0, 12))
],
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
print("boosm");
},
child: Text("Tap")),
],
),
),
),
],
),
),
);
}
}
TL;DR I fixed the problem by using a normal AppBar() since I didn't need a SliverAppBar(). I made a custom app bar to fix the problem (see code at the end of the question).
I realised I didn't need a SilverAppBar() because it will just stay floating and pinned. This made my life a whole lot easier since I could use an AppBar() and set the extendBodyBehindAppBar to true in the Scaffold(). This made it so that I wouldn't have to make a custom sliver widget as I am not familiar with making them.
My solution was to make a custom AppBar(). I would have a Stack() then put the blur effect and the AppBar() above it.
https://github.com/flutter/flutter/issues/48212 shows that you can't use ShaderMasks() with BackdropFilter()s. To work around this I made a column with a bunch of BackdropFilter()s. They would have decreasing sigma values to create the gradient effect I was looking for. This isn't very performant, however, and in heavier apps wouldn't work well. Making each block have the length of a single logical pixel was too heavy so I made it 2 logical pixels.
It can also be easily expanded, for example, by adding a fade effect as I did.
Here is what the result looks like.
Before: https://cln.sh/vcCY4j
After:
https://cln.sh/vNZVJW (Includes the opacity effect (0.8))
https://cln.sh/jfH7OP (Reduced opacity effect (0.5))
https://cln.sh/nXzPLe (No opacity effect)
Here is the code for the solution:
import 'dart:math';
import 'dart:ui';
import 'package:flutter/material.dart';
class BlurredAppBar extends StatelessWidget implements PreferredSizeWidget {
final String title;
final List<Widget>? actions;
/// An `AppBar()` which has a blur effect behind it which fades in to hide it
/// until content appears behind it. This has a similar effect to the iOS 14
/// App Library app bar. It also has the possibility of having a fade effect to
/// redude the opacity of widgets behind the `BlurredAppBar()` using a `LinearGradient()`.
const BlurredAppBar({required this.title, this.actions, Key? key})
: super(key: key);
/// The height of the `AppBar()`
final double height = 56;
/// Returns a `List<Widget>` of `BackdropFilter()`s which have decreasing blur values.
/// This will create the illusion of a gradient blur effect as if a `ShaderMask()` was used.
List<Widget> _makeBlurGradient(double height, MediaQueryData mediaQuery) {
List<Widget> widgets = [];
double length = height + mediaQuery.padding.top;
for (int i = 1; i <= (length / 2); i++) {
widgets.add(
ClipRRect(
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: max(((length / 2) - i.toDouble()) / 2, 0),
sigmaY: min(5, max(((length / 2) - i.toDouble()) / 2, 0)),
),
child: SizedBox(
height: 2,
width: mediaQuery.size.width,
),
),
),
);
}
return widgets;
}
#override
Widget build(BuildContext context) {
final MediaQueryData mediaQuery = MediaQuery.of(context);
return Stack(
children: [
// BackdropFilters
SizedBox(
height: height + mediaQuery.padding.top,
child: Column(
children: _makeBlurGradient(height, mediaQuery),
),
),
// Fade effect.
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
stops: [0.5, 1],
colors: [
Colors.white.withOpacity(0.8),
Colors.white.withOpacity(0),
],
),
),
),
// AppBar
AppBar(
title: Text(
title,
style: Theme.of(context).textTheme.headline3,
),
automaticallyImplyLeading: false,
actions: actions,
),
],
);
}
#override
Size get preferredSize => Size.fromHeight(height);
}
SliverAppBar(
primary: false,
toolbarHeight: kToolbarHeight * 1.5,
floating: true,
snap: true,
backgroundColor: Colors.black45,
titleSpacing: 0.0,
title: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 36.0, sigmaY: 36.0),
child: SizedBox(
width: MediaQuery.of(context).size.width,
height: kToolbarHeight * 1.5,
),
),
)
You can change toolbarHeight to your liking, but the child of the BackdropFilter must have the same height.

How to make a container take up the height of the parent widget?

I have a card layout which looks like the following:
The code for it it as follows:
Card(
color: tap ? Colors.green : Colors.white,
margin: EdgeInsets.symmetric(horizontal: 5.0, vertical: 3.0),
child: Container(
child: Row(
children: [
**Container(
height: !widget.menuItem.image.endsWith('/')? 70.0 : 0.0,
width: !widget.menuItem.image.endsWith('/')? 70.0 : 0.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(topLeft: Radius.circular(5.0), topRight: Radius.circular(5.0)),
image: DecorationImage(
image: NetworkImage(widget.menuItem.image),
fit: BoxFit.cover
),
),**
),
SizedBox(
width: 8.0,
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Text(
howManyThere() > 0 ? "${howManyThere()} x " : '',
style: addBTNHighlight,
),
Expanded(
child: Text(
widget.menuItem.item_name,
overflow: TextOverflow.ellipsis,
style: tap ? TitleWhite18Bold : Title18bold,
),
),
],
),
Container(
child: Text(
widget.menuItem.description,
//overflow: TextOverflow.ellipsis,
style: tap ? SubTitleWhite13 : SubTitle13,
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Text(
"£" + num.parse(widget.menuItem.price).toStringAsFixed(2),
style: tap ? priceHighlightSelected : priceHighlight,
),
),
],
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 30.0, vertical: 6.0),
decoration: BoxDecoration(),
child: Text("ADD", style: tap ? priceHighlightWhite : addBTNHighlight)),
],
),
],
),
),
)
As you can see that I am almost there with my desired layout but with one small issue which can be seen in first and last item. Because of the given width and height of the image container, it leaves a gap on top and bottom.
What I would like to happen is that the width to stay the same but the height to be flexible and adjust with the height of the card itself. Is it possible?
When I remove the height attribute of the container with the image, I get a blank space of the image
UPDATE: I tried LayoutBuilder as well but without any Luck, it throws 'Incorrect use of ParentWidget' Exception. The code I used is as follows:
Row(
children: [
widget.menuItem.image.endsWith('/')
? Container()
: **LayoutBuilder(
builder: (context, constraints){
return Container(
width: 70.0,
height: constraints.minHeight,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
image: DecorationImage(
image: NetworkImage(widget.menuItem.image),
fit: BoxFit.cover
),
),
);
}**
),
Try this :
Column(
children: [
Expanded(
child: Container(
width: !widget.menuItem.image.endsWith('/')? 70.0 : 0.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(topLeft: Radius.circular(5.0), topRight: Radius.circular(5.0)),
image: DecorationImage(
image: NetworkImage(widget.menuItem.image),
fit: BoxFit.cover
),
),
),
),
],
),
The problem here is your description text which overflow your desired max height. You can try to constraint your Container with a height: 70.0 or you can add to your Text widget the property maxLines: 1.
LayoutBuilder only give you constraints that parent pass to child, which is something like 100 < width < 200, 300 < height < infinity. At this point the height of all texts on the right are not determined yet, so it is impossible to determined the height of image base on that.
One way to do this is to assign key to each list item, get item heights after everything is layout, the rebuild with those fixed height. This will become a two pass process and is less efficient.
The official solution to this is IntrinsicHeight, which conceptually do the same thing, but in a more optimized way.
Here is a minimum example:
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: App(),
),
);
}
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: 10,
itemBuilder: (context, index) {
return Card(
clipBehavior: Clip.antiAliasWithSaveLayer,
// This is where magic happened
child: IntrinsicHeight(
child: Row(
children: [
Container(
width: 100,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage('https://cataas.com/cat'),
fit: BoxFit.cover,
),
),
),
Expanded(
child: Text(
// just put some random text with dynamic height
'Text\n' * (Random().nextInt(4) + 4),
),
),
],
),
),
);
},
),
);
}
}
Remove height constraints, then
Try replacing fit: BoxFit.cover with BoxFit.fitHeight or BoxFit.fill.
In order to fill the image with card height you can give container required height and wrap the Image widget in AspectRatio widget with ratio 1. This will always helps image widget to fill parent card height. Have a look in below code.
Parent Widget
Container(
margin: EdgeInsets.only(bottom: 12),
height: 100,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
AspectRatio(
aspectRatio: 1,
child: _pictureWidget(widget.menuItem.image),
),
/// Replace `Container` with the needed widget
Expanded(child: Container()),
],
),
)
_pictureWidget
Widget _picture(String url) {
return _pictureWidget(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(5.0), topRight: Radius.circular(5.0)),
child: Image.network(
url != null ? url : "",
fit: BoxFit.cover,
loadingBuilder: (BuildContext context, Widget child,
ImageChunkEvent loadingProgress) {
if (loadingProgress == null) return child;
return Center(
child: CircularProgressIndicator(
value: loadingProgress.expectedTotalBytes != null
? loadingProgress.cumulativeBytesLoaded /
loadingProgress.expectedTotalBytes
: null,
),
);
},
),
);
}

How do I do the "frosted glass" effect in Flutter?

I'm writing a Flutter app, and I'd like to use/implement the "frosted glass" effect that's common on iOS. How do I do this?
You can use the BackdropFilter widget to achieve this effect.
import 'dart:ui';
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(home: new FrostedDemo()));
}
class FrostedDemo extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new Stack(
children: <Widget>[
new ConstrainedBox(
constraints: const BoxConstraints.expand(),
child: new FlutterLogo()
),
new Center(
child: new ClipRect(
child: new BackdropFilter(
filter: new ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
child: new Container(
width: 200.0,
height: 200.0,
decoration: new BoxDecoration(
color: Colors.grey.shade200.withOpacity(0.5)
),
child: new Center(
child: new Text(
'Frosted',
style: Theme.of(context).textTheme.display3
),
),
),
),
),
),
],
),
);
}
}
I think I don't know the exact meaning of 'Frosted'(If my example didnot work here),
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
void main() => runApp(
MaterialApp(
title: "Frosted glass",
home: new HomePage()
)
);
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new Stack(
fit: StackFit.expand,
children: <Widget>[
generateBluredImage(),
new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
rectShapeContainer(),
],
),
],
),
);
}
Widget generateBluredImage() {
return new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage('assets/images/huxley-lsd.png'),
fit: BoxFit.cover,
),
),
//I blured the parent container to blur background image, you can get rid of this part
child: new BackdropFilter(
filter: new ui.ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0),
child: new Container(
//you can change opacity with color here(I used black) for background.
decoration: new BoxDecoration(color: Colors.black.withOpacity(0.2)),
),
),
);
}
Widget rectShapeContainer() {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 40.0, vertical: 10.0),
padding: const EdgeInsets.all(15.0),
decoration: new BoxDecoration(
//you can get rid of below line also
borderRadius: new BorderRadius.circular(10.0),
//below line is for rectangular shape
shape: BoxShape.rectangle,
//you can change opacity with color here(I used black) for rect
color: Colors.black.withOpacity(0.5),
//I added some shadow, but you can remove boxShadow also.
boxShadow: <BoxShadow>[
new BoxShadow(
color: Colors.black26,
blurRadius: 5.0,
offset: new Offset(5.0, 5.0),
),
],
),
child: new Column(
children: <Widget>[
new Text(
'There\'s only one corner of the universe you can be certain of improving and that\'s your own self.',
style: new TextStyle(
color: Colors.white,
fontSize: 20.0,
),
),
],
),
);
}
}
Outcome:
I hope this will help someone.
BackdropFilter(
filter: ImageFilter.blur(sigmaX: _sigmaX, sigmaY: _sigmaY),
child: Container(
color: Colors.black.withOpacity(_opacity),
),
),