在 Flutter 开发中,实现玻璃模糊效果(Glassmorphism)能够显著提升用户界面的视觉吸引力。本文提供了详细的实现步骤和代码示例,帮助开发者在 Flutter 中轻松创建 Glassmorphic 界面。通过掌握这一设计技巧,您可以为应用增添现代感与层次感,打造出更具吸引力的用户体验。

Flutter 实现 Glassmorphic 高斯模糊效果

Glassmorphic

视频

前言

原文 Flutter 实现玻璃模糊效果

参考

https://api.flutter.dev/flutter/painting/LinearGradient-class.html

https://api.flutter.dev/flutter/painting/BoxDecoration-class.html

https://api.flutter.dev/flutter/painting/LinearGradient-class.html

正文

我们写了 4 个类:

  1. ColorBackground . 只是一个具有颜色和不透明度的容器。
  2. GradientBackground . 带有渐变、不透明度和模糊的容器。
  3. ImageBackground . 包含图像、不透明度和模糊效果的容器。
  4. TranslucentPanel.

前三个旨在用作背景,并且可以将它们组合使用。创建这些自定义小部件的主要目的是使视图的代码更简单和简洁。

这里有一些例子:

ColorOverGradientView

在左边,我放置了 GradientBackground,其不透明度为 1.0,并在其上放置了 ColorBackground。在右边——相反。

有一件事情对我来说很有趣,就是是否先放什么东西会有区别。结果显示并没有。我们可以通过调整顶部背景的不透明度来获得几乎相同的结果。

以下是 Golor over Gradient 示例的全部代码:

class ColorOverGradientView extends GetView<ColorOverGradientController> {
  const ColorOverGradientView({super.key});
  @override
  Widget build(BuildContext context) {
    return GradientBackground(
      colors: [Colors.purple, Colors.black, Colors.red, Colors.blue],
      child: ColorBackground(
        color: Colors.lightBlueAccent,
        opacity: 0.4,
        child: Scaffold(
          backgroundColor: Colors.transparent,
          appBar: AppBar(
            leading: CupertinoButton(
                child: Icon(Icons.chevron_left, color: Colors.white, size: 30,),
                onPressed: () {
                  Get.back();
                }),
            backgroundColor: Colors.transparent,
          ),
          body:  Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                TranslucentPanel(
                  width: 300,
                  height: 100,
                  child: Center(
                    child: Text(
                      'Color Over Gradient',
                      style: TextStyle(fontSize: 30,  color: Colors.white70),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

图像上的颜色:

img

在右侧,我添加了一些模糊效果。

以下是所有三个背景和半透明面板的代码:

color_background.dart

import 'package:flutter/material.dart';
import 'package:getx_glassmorphic_no_package/app/modules/ui_extensions.dart';

final class ColorBackground extends StatelessWidget {
  final double width;
  final double height;
  final Color color;
  final double opacity;
  final Widget? child;

  const ColorBackground(
      {super.key,
      this.width = double.infinity,
      this.height = double.infinity,
      required this.color,
      this.opacity = 1,
      this.child});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: width,
      height: height,
      color: color.withOpacityExt(opacity),
      child: child,
    );
  }
}

唯一必需的参数是 color

gradient_background.dart

import 'dart:ui';
import 'package:flutter/material.dart';

final class GradientBackground extends StatelessWidget {
  final double width;
  final double height;
  final List<Color> colors;
  final double opacity;
  final Widget? child;
  final GradientType gradientType; //circular, linear, sweep
  final Gradient? gradient;
  final double blur;

  const GradientBackground({
    super.key,
    this.width = double.infinity,
    this.height = double.infinity,
    required this.colors,
    this.opacity = 1.0,
    this.child,
    this.gradientType = GradientType.linear,
    this.gradient,
    this.blur = 0,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      width: width,
      height: height,
      decoration: BoxDecoration(
        gradient: gradient ?? _createGradient(colors, opacity, gradientType),
      ),
      child: BackdropFilter(
        filter: ImageFilter.blur(sigmaX: blur, sigmaY: blur),
        child: child,
      ),
    );
  }

  Gradient _createGradient(
    List<Color> colors,
    double opacity,
    GradientType gradientType,
  ) {
    switch (gradientType) {
      case GradientType.radial:
        return RadialGradient(colors: colors).withOpacity(opacity);
      case GradientType.sweep:
        return SweepGradient(colors: colors).withOpacity(opacity);

      default:
        return LinearGradient(
                colors: colors,
                begin: Alignment.topLeft,
                end: Alignment.bottomRight)
            .withOpacity(opacity);
    }
  }
}

enum GradientType { linear, radial, sweep }

唯一必需的参数是 colors ( List<Color> )。

image_background.dart

import 'dart:ui';
import 'package:flutter/material.dart';

final class ImageBackground extends StatelessWidget {
  final double width;
  final double height;
  final ImageProvider<Object> image;
  final double opacity;
  final Widget? child;
  final double blur;

  const ImageBackground(
      {super.key,
      this.width = double.infinity,
      this.height = double.infinity,
      required this.image,
      this.opacity = 1,
      this.blur = 0,
      this.child});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: width,
      height: height,
      decoration: BoxDecoration(
        image: DecorationImage(
          image: image,
          fit: BoxFit.cover,
          opacity: opacity,
        ),
      ),
      child: BackdropFilter(
        filter: ImageFilter.blur(sigmaX: blur, sigmaY: blur),
        child: child,
      ),
    );
  }
}

唯一必需的参数是 image

translucent_panel.dart

import 'package:flutter/material.dart';
import 'package:getx_glassmorphic_no_package/app/modules/ui_extensions.dart';

final class TranslucentPanel extends StatelessWidget {
  final double width;
  final double height;
  final double borderRadius;
  final Widget? child;

  const TranslucentPanel(
      {super.key,
      this.width = double.infinity,
      this.height = double.infinity,
      this.borderRadius = 12,
      this.child});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: width,
      height: height,
      decoration: BoxDecoration(
        gradient: LinearGradient(colors: [
          Colors.white,
          Colors.white.withOpacityExt(0.9),
          Colors.white,
          Colors.white.withOpacityExt(0.9),
        ]).withOpacity(0.15),
        border: Border.all(
          color: Colors.white,
          width: 0.5,
        ),
        borderRadius: BorderRadius.all(Radius.circular(borderRadius)),
      ),
      child: child,
    );
  }
}

TranslucentPanel 没有必需的参数,但在大多数情况下,我们应该指定 width height 。否则,它将占据整个屏幕。

好的,最后一个例子是 Gradient over Image。

img

从左到右:线性、径向和扫掠渐变。线性,依我之见,完美地融合到了图像中。

这里是线性代码:

class GradientOverImageView extends GetView<GradientOverImageController> {
  const GradientOverImageView({super.key});
 @override
  Widget build(BuildContext context) {
    return ImageBackground(
      image: NetworkImage(
            'https://images.unsplash.com/photo-1460627390041-532a28402358?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'),
      child: GradientBackground(
        gradientType: GradientType.linear,
        opacity: 0.6,
        colors: [Colors.purple, Colors.black, Colors.red, Colors.blue],
        child: Scaffold(
          backgroundColor: Colors.transparent,
          appBar: AppBar(
            leading: CupertinoButton(
                child: Icon(Icons.chevron_left, color: Colors.white, size: 30,),
                onPressed: () {
                  Get.back();
                }),
            backgroundColor: Colors.transparent,
          ),
          body:  Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                TranslucentPanel(
                  width: 300,
                  height: 100,
                  child: Center(
                    child: Text(
                      'Gradient Over Image',
                      style: TextStyle(fontSize: 30,  color: Colors.white70),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

要将其更改为径向或扫掠,我们只需相应地更改 gradientType 参数。

小结

本文详细介绍了如何在 Flutter 中实现玻璃模糊效果,包括代码示例和设计技巧,帮助开发者提升应用的视觉效果。

感谢阅读本文

如果有什么建议,请在评论中让我知道。我很乐意改进。


猫哥 APP

flutter 学习路径


© 猫哥 ducafecat.com

end