so I am currently having a grid of pictures and I want to implement a feature from instagram: If you longPress on one of the pictures, you get a a larger version of that pic
Here's the improved vewrsion that resembles the same exact UX as of Instagram with blurred background.
We can achieve this using a combination of Stateful Widget
, Stack
and BackdropFliter
, here is the sample code -
import 'dart:ui';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Counter Demo',
theme: ThemeData.light(),
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.blueGrey,
centerTitle: true,
title: Text("Demo App"),
),
body: Stacked(),
),
);
}
}
class Stacked extends StatefulWidget {
@override
_StackedState createState() => _StackedState();
}
class _StackedState extends State {
final List images = [
"1.jpg",
"2.jpg",
"3.jpg",
"4.jpg",
"5.jpg",
"6.jpg",
"7.jpg",
"8.jpg",
"9.jpg",
"10.jpg",
];
bool _showPreview = false;
String _image = "assets/images/1.jpg";
@override
Widget build(BuildContext context) {
return SafeArea(
child: Stack(
children: [
GridView.builder(
itemCount: images.length,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onLongPress: () {
setState(() {
_showPreview = true;
_image = "assets/images/${images[index]}";
});
},
onLongPressEnd: (details) {
setState(() {
_showPreview = false;
});
},
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Card(
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
),
clipBehavior: Clip.hardEdge,
child: Image.asset("assets/images/${images[index]}"),
),
),
);
},
),
if (_showPreview) ...[
BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 5.0,
sigmaY: 5.0,
),
child: Container(
color: Colors.white.withOpacity(0.6),
),
),
Container(
child: Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: Image.asset(
_image,
height: 300,
width: 300,
),
),
),
),
],
],
));
}
}
This is just a baseline example and there are endless possibilities you can modify this to achieve behavior you want.
Another simple way is we can build this by using StatefulWidget and IndexedStack -
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Counter Demo',
theme: ThemeData.light(),
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.blueGrey,
centerTitle: true,
title: Text("Demo App"),
),
body: Body(),
),
);
}
}
class Body extends StatefulWidget {
@override
_BodyState createState() => _BodyState();
}
class _BodyState extends State {
final List images = [
"1.jpg",
"2.jpg",
"3.jpg",
"4.jpg",
"5.jpg",
"6.jpg",
"7.jpg",
"8.jpg",
"9.jpg",
"10.jpg",
];
int _index = 0;
String _image = "assets/images/1.jpg";
@override
Widget build(BuildContext context) {
return SafeArea(
child: IndexedStack(
index: _index,
children: [
GridView.builder(
itemCount: images.length,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onLongPress: () {
setState(() {
_index = 1;
_image = "assets/images/${images[index]}";
});
},
onLongPressEnd: (details) {
setState(() {
_index = 0;
});
},
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Card(
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
),
clipBehavior: Clip.hardEdge,
child: Image.asset("assets/images/${images[index]}"),
),
),
);
},
),
Container(
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
),
child: Center(
child: ConstrainedBox(
constraints: BoxConstraints(
maxHeight: 400,
maxWidth: 400,
),
child: Image.asset(
_image,
),
),
),
)
],
),
);
}
}
You can check output for above code here.