Android Material Design 陰影實現

Reiser實驗室發表於2018-04-22

讓 View 產生陰影有以下 4 種方式:

  1. 控制 elevation
  2. 使用 OutlineProvider
  3. 使用 9 圖
  4. 使用 MD 風格的控制元件,如 CardView,FloatingActionButton

0.Z軸的概念 Android 在 5.0 及以後採用了 Material Design 設計語言,引入了 Z 軸的概念,也就是垂直於螢幕的軸,Z 軸會讓 View 產生陰影的效果:

shadows-depth.png

想象有一束斜光投向螢幕,Z 軸值越大,離光就越近,陰影的範圍就越大;Z 軸值越小,離光就越遠,陰影的範圍就越小。而:

Z=elevation+ translationZ

elevation 一般是寫在 xml 檔案中做靜態配置,translateZ 是用來控制動畫效果。

是 Z 軸讓 View 產生了陰影,我們要控制陰影就是控制 Z 軸啦:

1.控制 elevation 控制 elevation,需要先設定 View 的 BackGround,再設定 elevation。

首先配置一個 drawable:

<!-- res/drawable/myrect.xml -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <solid android:color="#42000000" />
    <corners android:radius="5dp" />
</shape>
複製程式碼

再設定 background 和 elevation:

<TextView
    android:id="@+id/myview"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:elevation="2dp"
    android:background="@drawable/myrect" />
複製程式碼

效果圖

2.使用 OutlineProvider

第 1 種方式可以滿足大多數情況,但如果 View 的 background 是 color、圖片,甚至是自定義 View 時就無法產生陰影效果了,這是我們需要通過程式碼設定陰影。官方稱之為 outline。

        view.setOutlineProvider(new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                outline.setRect(0,0,view.getWidth(),view.getHeight());
            }
        });
複製程式碼

outline 就是繪製的外部陰影樣式,樣式可以是任意的:矩形、園、圓角矩形、甚至是路徑:

outline的方法

3.使用 9 圖

前面兩種方法涵蓋了大多數情況,實在還有意外:比如相容 5.0 之前的 UI 樣式、UI設計的陰影居然是彩色的!那就使用最後的絕招了: 9 圖。不過使用 9 圖的靈活性實在是差,高度不同就要不同的切圖,這裡有一個網站可以自己隨意切陰影圖:inloop.github.io/shadow4andr…

4.使用官方 MD 元件

其實官方元件的 ActionBar、CardView,FloatingActionButton就自帶陰影,應儘量使用他們,這裡就不展開講了。

5.translateZ 動畫

介紹 Z 軸時,說過 Z=elevation+ translationZ。elevation 是靜態的,而 translateZ 是動態的。如我們點選按鈕時希望它有一個彈起的效果,像這樣:

彈起
其實是給 view 配置狀態動畫控制 translationZ:

android:stateListAnimator="@drawable/selector_elevation"

動畫 xml 如下

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="true" android:state_pressed="true">
        <objectAnimator
            android:duration="@android:integer/config_shortAnimTime"
            android:propertyName="translationZ"
            android:valueTo="8dp"
            android:valueType="floatType" />
    </item>
    <item>
        <objectAnimator
            android:duration="@android:integer/config_shortAnimTime"
            android:propertyName="translationZ"
            android:valueTo="0dp"
            android:valueType="floatType" />
    </item>
</selector>
複製程式碼

相關文章