Reputation: 120689
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?
Upvotes: 174
Views: 164850
Reputation: 116798
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 Scaffold(
body: Stack(
children: <Widget>[
ConstrainedBox(
constraints: const BoxConstraints.expand(),
child: FlutterLogo()
),
Center(
child: ClipRect(
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
child: Container(
width: 200.0,
height: 200.0,
decoration: BoxDecoration(
color: Colors.grey.shade200.withOpacity(0.5)
),
child: Center(
child: Text(
'Frosted',
style: Theme.of(context).textTheme.headlineLarge
),
),
),
),
),
),
],
),
);
}
}
Upvotes: 366
Reputation: 531
BackdropFilter constructor:
BackdropFilter({
Key? key,
required ImageFilter filter,
Widget? child,
BlendMode blendMode = BlendMode.srcOver
})
ImageFilter.blur constructor:
ImageFilter.blur({
double sigmaX = 0.0,
double sigmaY = 0.0,
TileMode tileMode = TileMode.clamp
})
Example 1: Blurred Background Image
Preview:
// main.dart
import 'package:flutter/material.dart';
import 'dart:ui';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
// Remove the debug banner
debugShowCheckedModeBanner: false,
title: 'Kindacode.com',
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: NetworkImage(
'https://www.kindacode.com/wp-content/uploads/2021/04/background.jpeg'),
fit: BoxFit.cover)),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
child: Center(
child: Card(
elevation: 10,
color: Colors.black.withOpacity(0.5),
child: const SizedBox(
width: 300,
height: 200,
child: Center(
child: Text(
'Some Text',
style: TextStyle(fontSize: 30, color: Colors.white),
),
),
),
),
),
),
),
);
}
}
Upvotes: 1
Reputation: 111
BackdropFilter(
filter: ImageFilter.blur(sigmaX: _sigmaX, sigmaY: _sigmaY),
child: Container(
color: Colors.black.withOpacity(_opacity),
),
),
Upvotes: 10
Reputation: 22437
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.
Upvotes: 26