FlutterComponent最佳实践之Shadow怎么就这么简单

设计三件宝,模糊阴影和圆角。这些在原生开发中被设计摧残N年的东西,在Flutter中,居然是轻而易举的实现。

添加Shadow

在Flutter中,Container可以使用BoxDecoration来添加Shadow,如果是单独的Widget,可以通过DecoratedBox来添加阴影。

下面我们以Container为例,演示Flutter的Shadow实现。原始效果如图所示。

child: Container(
  height: 100,
  width: 100,
  decoration: BoxDecoration(
    color: Colors.white,
    borderRadius: BorderRadius.circular(8),
    shape: BoxShape.rectangle,
    boxShadow: const [
      BoxShadow(),
    ],
  ),
)

在Flutter中,阴影本身并不模糊,其大小也足以使其可见。BoxShadow有几个属性可以让我们对它进行配置,我们将使用这三个属性。

  • Offset
  • Blur radius
  • Spread radius

由此可见,Flutter不愧是Chrome团队的产物,这些参数和CSS中的Shadow参数是一致的,当然这也方便了开发者和设计师的沟通。

首先,我们来看一下Offset。它代表阴影相对于当前Widget的偏移量,它的效果就好比我们将光源放置在物体的左上角,那么阴影将偏移至右下角这样的效果。

我们设置Offset(4, 4),效果如上所示。

你可以发现,阴影不会被Blur,所以,我们使用blurRadius这个参数,来控制阴影被Blur的程度,通过spreadRadius来控制阴影向外扩散的程度,当你不设置它时,阴影与原始Widget是同样的大小。

了解了这些参数之后,我们找到设计稿,找到相应的参数配置,就得到了下面这个阴影。

child: Container(
  height: 100,
  width: 100,
  decoration: BoxDecoration(
    color: Colors.white,
    borderRadius: BorderRadius.circular(8),
    shape: BoxShape.rectangle,
    boxShadow: [
      BoxShadow(
        color: Colors.black.withAlpha(25),
        offset: const Offset(0, 14),
        blurRadius: 24,
        spreadRadius: 0,
      ),
    ],
  ),
)

这可能就是国内设计师梦寐以求的阴影吧。

PhysicalModel & PhysicalShape

Flutter的组件茫茫多,PhysicalModel和PhysicalShape这两个组件,也同样能模拟阴影的实现,但它的实现实际上是Material Design中的elevation的实现效果,代码如下所示。

return Center(
  child: PhysicalModel(
    borderRadius: BorderRadius.circular(20),
    color: Colors.white,
    elevation: 16,
    shadowColor: Colors.black.withAlpha(25),
    child: const SizedBox(
      height: 100,
      width: 100,
    ),
  ),
);

Text Shadow

在TextStyle中,同样支持Shadows参数。

child: Text(
  "中华人民共和国",
  style: TextStyle(
    fontSize: 32,
    fontWeight: FontWeight.w700,
    shadows: [
      Shadow(
        color: Colors.red.shade300,
        blurRadius: 8,
        offset: const Offset(2, 2),
      )
    ],
  ),
)

除此之外,文字阴影还有一种实现,那就是通过BackdropFilter来进行模拟,BackdropFilter的作用也是创建Blur效果,所以,它也可以用来替代阴影,但是效果没有Shadow灵活(类似的还有ImageFiltered)。

var style = const TextStyle(
  fontSize: 32,
  fontWeight: FontWeight.w700,
);
var text = "中华人民共和国";
return Center(
  child: Stack(
    children: [
      Text(
        text,
        style: style,
      ),
      BackdropFilter(
        filter: ui.ImageFilter.blur(
          sigmaX: 2,
          sigmaY: 2,
        ),
        child: Text(
          text,
          style: style,
        ),
      )
    ],
  ),
);

Neumorphism

Neumorphism是一种全新的设计风格,通常被称为新的拟物风格,它其实就是通过阴影来实现的。

拟态阴影通常都由两个Shadow组合而成,一个Shadow比Widget Color更浅,另一个Shadow更深,我们通过下面这个例子来看下如何实现拟态阴影。

return Center(
  child: Text(
    '中华人民共和国',
    style: TextStyle(
      fontWeight: FontWeight.bold,
      fontSize: 40,
      shadows: [
        const Shadow(
          offset: Offset(3, 3),
          color: Colors.black38,
          blurRadius: 10,
        ),
        Shadow(
          offset: const Offset(-3, -3),
          color: Colors.white.withOpacity(0.85),
          blurRadius: 10,
        ),
      ],
      color: Colors.grey.shade300,
    ),
  ),
);

在shadows中配置两个相对于中心互相偏离的Shadow,并使得它们的颜色是互补的,例如黑和白,而Widget Color通常和背景色相同。

例如下面这样的配置:

light mode:
Background color: Color(0xFFEFEEEE)
Light shadow: Colors.white.withOpacity(0.8),
Dark shadow: Colors.black.withOpacity(0.1)

dark mode:
Background color: Color(0xFF292D32)
Light shadow: Colors.white.withOpacity(0.1),
Dark shadow: Colors.black.withOpacity(0.4)

如果是Container的话,类似上面的Shadow实现,代码如下所示。

return Center(
  child: Container(
    height: 200,
    width: 200,
    decoration: BoxDecoration(
      borderRadius: BorderRadius.circular(16),
      color: Colors.grey.shade300,
      boxShadow: [
        const BoxShadow(
          offset: Offset(10, 10),
          color: Colors.black38,
          blurRadius: 20,
        ),
        BoxShadow(
          offset: const Offset(-10, -10),
          color: Colors.white.withOpacity(0.85),
          blurRadius: 20,
        ),
      ],
    ),
  ),
);

由此可见,拟物阴影的核心,实际上就是两组互补色的阴影叠加,当Widget Color和背景色相同时,在边缘就会产生类似拟物的阴影风格。

通过下面这个工具,你可以方便的设计拟物阴影,找到不同的颜色下的最佳效果。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,961评论 5 473
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,444评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,009评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,082评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,101评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,271评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,738评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,395评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,539评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,434评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,481评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,160评论 3 317
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,749评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,816评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,038评论 1 256
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,548评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,140评论 2 341

推荐阅读更多精彩内容

  • 对页面来说文字就是灵魂,因此美化文字的工作必不可少。除了加载漂亮的字体外,还可以用text-shadow文本阴影给...
    张歆琳阅读 1,387评论 0 12
  • github地址 系统控件 TextView一个功能强大的TextView,可以满足日常大部分布局方式Facebo...
    哇哇_刘阅读 749评论 0 5
  • 设计图如上,关于那个阴影渐变的实现。最初的时候,我是采用渐变实现,结果发现在手机上测试的时候,变成了一个灰色的条,...
    EJRoxy阅读 623评论 0 0
  • Dart 控件 https://api.flutter.dev/flutter/widgets/widgets-l...
    CodingTom阅读 1,632评论 0 3
  • 我对任何美的东西都会本能地生出一种爱,在CSS的世界里,凡和色彩渐变等沾边的属性都是我的菜。因此box-shado...
    张歆琳阅读 6,571评论 6 33