flutteruser-interfaceflutter-layoutpaintflutter-custompaint

is it possible to give gradient blur effect in Custom paint in Flutter like below picture?


I am coding the below output and i get the design i want but not able to get the blur effect inside the canvas.

This is the output i am trying to build,
Output i want

This is what i have tried, My Output

Here is the Code,

class MyCustomPainter extends CustomPainter {

@override



 void paint(Canvas canvas, Size size) {
    Paint paint0 = Paint()
      ..color = const Color.fromARGB(128,255,255,255)
    ..style = PaintingStyle.fill
    ..strokeWidth = 2.0;

Path path0 = Path();
path0.moveTo(size.width * 0.1500300, size.height * 0.1238500);
path0.cubicTo(
    size.width * 0.0037200,
    size.height * 0.1023500,
    size.width * 0.0522600,
    size.height * 0.7552500,
    size.width * 0.1500500,
    size.height * 0.8761750);
path0.cubicTo(
    size.width * 0.2767600,
    size.height * 0.8761750,
    size.width * 0.7234100,
    size.height * 0.8735500,
    size.width * 0.8501100,
    size.height * 0.8735500);
path0.cubicTo(
    size.width * 0.9464300,
    size.height * 0.7575750,
    size.width * 0.9946900,
    size.height * 0.0944750,
    size.width * 0.8496900,
    size.height * 0.1268750);
path0.cubicTo(
    size.width * 0.7230200,
    size.height * 0.1268750,
    size.width * 0.5303400,
    size.height * 0.1263500,
    size.width * 0.1500300,
    size.height * 0.1238500);
path0.close();
canvas.drawPath(path0, paint0);


}

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

Thanks in advance!


Solution

  • You don't need to bother yourself with a CustomPainter everything can be done with a Container and a BackdropFilter widgets.

    Code sample

    class BlurredBottomBar extends StatelessWidget {
      const BlurredBottomBar({
        super.key,
        required this.items,
        required this.currentIndex,
        required this.onItemTapped,
      });
    
      final int currentIndex;
      final void Function(int index) onItemTapped;
      final List<IconData> items;
    
      @override
      Widget build(BuildContext context) {
        final theme = Theme.of(context);
        final bottomNavigationBarTheme = theme.bottomNavigationBarTheme;
    
        return Container(
          margin: const EdgeInsets.all(12),
          padding: const EdgeInsets.all(12),
          clipBehavior: Clip.antiAlias,
          decoration: BoxDecoration(
            border: Border.all(
              color: Colors.white,
              strokeAlign: BorderSide.strokeAlignOutside,
            ),
            borderRadius: const BorderRadius.vertical(
              top: Radius.circular(9),
              bottom: Radius.circular(36),
            ),
          ),
          child: BackdropFilter(
            filter: ImageFilter.blur(sigmaX: 2, sigmaY: 2),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                for (int i = 0; i < items.length; i++)
                  IconButton(
                    onPressed: () => onItemTapped(i),
                    icon: Icon(
                      items[i],
                      color: i == currentIndex
                          ? bottomNavigationBarTheme.selectedItemColor
                          : bottomNavigationBarTheme.unselectedItemColor,
                    ),
                  ),
              ],
            ),
          ),
        );
      }
    }
    

    Usage

    Scaffold(
      extendBody: true,
      bottomNavigationBar: BlurredBottomBar(
        currentIndex: 0,
        items: const [
          Icons.home,
          Icons.grid_view,
          Icons.notifications_outlined,
          Icons.settings_outlined,
        ],
        onItemTapped: (index) {
          // ...
        },
      ),
      body: ...,
    );
    

    Screenshot

    enter image description here

    You can try the full example on zapp.run