1. 程式人生 > 其它 >FlutterComponent最佳實踐之Shadow怎麼就這麼簡單

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和背景色相同時,在邊緣就會產生類似擬物的陰影風格。

通過下面這個工具,你可以方便的設計擬物陰影,找到不同的顏色下的最佳效果。