I have been able to get up to the very closed result you needed. Especially the blur effect. The key elements used are ClipRRect, ClipPath, BackdropFilter.
I have used other elements as well, but it's upto you. The idea is to clip the rectangle diagonally, so that one side is blurred and other side is transparent. Also clipping restricts the effect of backdrop filter's outside the rectangle, otherwise it causes blur effect on the entire screen.
If you play around a little with various color values with opacity, you can get the exact result.
You can also look for the results at this Dartpad link
main.dart file.
import 'dart:ui';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: false,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
Widget drawRowItem(BuildContext context) {
return Expanded(
child: Container(
margin: const EdgeInsets.symmetric(vertical: 12),
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(16)),
border: Border.all(
width: 2, color: const Color.fromARGB(255, 40, 40, 40))),
height: 200,
child: const Padding(
padding: EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(
Icons.home_filled,
color: Colors.white,
),
SizedBox(height: 8),
Text(
"Samle Item",
style: TextStyle(
color: Colors.white,
),
),
],
),
),
),
);
}
Widget drawRowItems(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.width / 2 - 56,
width: MediaQuery.of(context).size.width / 2 - 56,
margin: const EdgeInsets.symmetric(horizontal: 22),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
drawRowItem(context),
const SizedBox(
width: 16,
),
drawRowItem(context)
],
),
);
}
@override
Widget build(BuildContext context) {
List<int> items = List.filled(40, 0);
return Scaffold(
backgroundColor: Colors.black,
body: Stack(
fit: StackFit.expand,
children: [
ListView(
children: items.map((e) {
return drawRowItems(context);
}).toList(),
),
Positioned(
bottom: 18,
left: 18,
right: 18,
height: 86,
child: Container(
decoration: BoxDecoration(
border: Border.all(
width: 2, color: const Color.fromARGB(255, 40, 40, 40)),
borderRadius: const BorderRadius.only(
topRight: Radius.circular(24),
topLeft: Radius.circular(24),
bottomLeft: Radius.circular(52),
bottomRight: Radius.circular(52)),
color: const Color.fromARGB(100, 40, 40, 40)
),
child: ClipRRect(
borderRadius: const BorderRadius.only(
topRight: Radius.circular(24),
topLeft: Radius.circular(24),
bottomLeft: Radius.circular(52),
bottomRight: Radius.circular(52)),
child: ClipPath(
clipper: MyCustomClipper(),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaY: 5, sigmaX: 5),
child: Container(),
),
),
),
),
),
const Positioned(
bottom: 18,
left: 22,
right: 22,
height: 86,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Icon(
Icons.home_outlined,
color: Colors.amber,
),
Icon(
Icons.apps,
color: Colors.white,
),
Icon(
Icons.notifications_outlined,
color: Colors.white,
),
Icon(
Icons.settings_outlined,
color: Colors.white,
),
],
),
),
],
),
);
}
}
class MyCustomClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
Path path = Path();
path.moveTo(0, 0);
path.lineTo(size.width, 0);
path.lineTo(64,size.height);
path.lineTo(0,size.height);
path.lineTo(0,0);
path.close();
return path;
}
@override
bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
return true;
}
}
