最近項目要求,ui有很多有關於陰影的設計要求,網上找了些實現方式,但都不是很理想。現在閑下來了,就尋思著自己寫個陰影佈局耍耍,以備後用。先說道說道我找到的幾種陰影實現方式: 系統陰影 Andorid 系統自api 21之後就多了一個熟悉 android:elevation ,這是android最新引 ...
最近項目要求,ui有很多有關於陰影的設計要求,網上找了些實現方式,但都不是很理想。現在閑下來了,就尋思著自己寫個陰影佈局耍耍,以備後用。先說道說道我找到的幾種陰影實現方式:
系統陰影
Andorid 系統自api 21之後就多了一個熟悉 android:elevation ,這是android最新引入的軸的概念,可通過設置elevation來設置陰影(z軸的大小),設置如下:
1 <!-- base z depth of the view. --> 2 <attr name="elevation" format="dimension" /> 3 4 <TextView 5 android:id="@+id/shadow1" 6 app:layout_constraintStart_toStartOf="parent" 7 app:layout_constraintTop_toTopOf="parent" 8 android:layout_marginStart="20dp" 9 android:layout_marginTop="20dp" 10 android:text="系統陰影" 11 android:background="#fff" 12 android:gravity="center" 13 android:textSize="14sp" 14 android:textColor="@color/colorBlack" 15 android:layout_width="100dp" 16 android:elevation="3dp" 17 android:layout_height="80dp"/>
效果也是不錯,可以完成一些簡單的陰影設置效果。
但需要註意些細節,不然 elevation 可能會無效:
- 父佈局要保留足夠的空間,elevation本身不占有view的大小
- 需要設置背景色且不可設置為透明色
- 不能設置是否為擴散的還是指定方向的
layer-list 偽陰影
為什麼說是偽陰影呢,layer-list本身很強大,器支持的層疊式繪製基本可以解決我們大多說的背景設計,對於一些要求不是很嚴格的陰影用它也不是不可以,但效果是真的不好,畢竟shape提供的層疊()並不支持模糊繪製(或者可以選擇使用模糊背景圖片繪製)。下麵給一個用layer-list繪製的陰影做參考。
1 <TextView 2 android:id="@+id/shadow2" 3 app:layout_constraintStart_toEndOf="@id/shadow1" 4 app:layout_constraintTop_toTopOf="parent" 5 android:layout_marginStart="50dp" 6 android:layout_marginTop="20dp" 7 android:text="layer-list陰影" 8 android:gravity="center" 9 android:background="@drawable/shadow_layer" 10 android:textSize="14sp" 11 android:textColor="@color/colorBlack" 12 android:layout_width="100dp" 13 android:layout_height="80dp"/> 14 15 16 17 <!--shadow_layer.xml --> 18 <?xml version="1.0" encoding="utf-8"?> 19 <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 20 21 <item android:top="3dp" 22 android:left="3dp"> 23 <shape android:shape="rectangle"> 24 <solid android:color="#333333"/> 25 <gradient android:startColor="#80ff0000" 26 android:type="radial" 27 android:centerX="0.5" 28 android:centerY="0.5" 29 android:gradientRadius="30" 30 android:endColor="#10ff0000"/> 31 <size android:width="100dp" android:height="80dp"/> 32 </shape> 33 </item> 34 35 <item android:bottom="3dp" 36 android:right="3dp"> 37 <shape android:shape="rectangle"> 38 <solid android:color="#fff"/> 39 <size android:width="100dp" android:height="80dp"/> 40 </shape> 41 </item> 42 43 </layer-list>
效果比較生硬,其本質就是顏色的漸變,如下:
還有如讓ui切陰影背景圖,但由於控制項大小規格差異較大,風格差異較大,並不推薦使用。
自定義陰影佈局
這是我比較推薦的方式,可參考CardView的陰影實現自定義一個陰影佈局實現。其實現是通過 setShadowLayer、setMaskFilter 實現。
1 // mPaint.setShadowLayer(blurRadius,0,0,shadowColor); 2 if (blurRadius>0){ 3 mPaint.setMaskFilter(new BlurMaskFilter(blurRadius,BlurMaskFilter.Blur.NORMAL)); 4 }
相較於 setShadowLayer 來說,setMaskFilter 可供選中的實現方式要多一個blur實現類型,效果更好些,所以我是通過使用 setMaskFilter 來實現自定義陰影佈局。
1 <cn.enjoytoday.shadow.ShadowLayout 2 android:id="@+id/shadow3" 3 app:layout_constraintStart_toStartOf="parent" 4 app:layout_constraintTop_toBottomOf="@id/shadow1" 5 android:layout_marginTop="20dp" 6 android:text="" 7 app:shadowRadius="0dp" 8 app:shadowColor="#333" 9 app:blurRadius="5dp" 10 app:xOffset="0dp" 11 app:yOffset="0dp" 12 android:layout_marginStart="15dp" 13 android:gravity="center" 14 android:background="@drawable/shadow_layer" 15 android:textSize="14sp" 16 android:textColor="@color/colorBlack" 17 android:layout_width="wrap_content" 18 android:layout_height="wrap_content"> 19 20 21 <TextView 22 android:padding="5dp" 23 android:text="自定義應用佈局" 24 android:gravity="center" 25 android:textSize="14sp" 26 android:textColor="@color/colorBlack" 27 android:layout_width="100dp" 28 android:layout_height="80dp"/> 29 30 </cn.enjoytoday.shadow.ShadowLayout>
使用
ShadowView 托管於GitHub, 仿照css的Box Shadow 的陰影實現效果設計實現,可通過設置水平、豎直偏移確認陰影方向,可設置模糊半徑和圓角半徑、陰影顏色等。可通過gradle直接依賴使用:
添加依賴
repositories {
//...
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.amikoj:ShadowView:1.0.1'
}
xml中使用
1 <cn.enjoytoday.shadow.ShadowLayout 2 android:orientation="vertical" 3 android:id="@+id/shadowLayout" 4 app:layout_constraintBottom_toBottomOf="parent" 5 app:layout_constraintLeft_toLeftOf="parent" 6 app:layout_constraintRight_toRightOf="parent" 7 app:layout_constraintTop_toTopOf="parent" 8 android:gravity="center" 9 app:shadowRadius="10dp" 10 app:shadowColor="#bebebe" 11 app:bgColor="#fff" 12 app:xOffset="10dp" 13 app:yOffset="0dp" 14 app:blurRadius="5dp" 15 android:layout_width="wrap_content" 16 android:layout_height="wrap_content"> 17 18 <!--嵌套需要添加陰影的佈局 --> 19 20 </cn.enjoytoday.shadow.ShadowLayout>
屬性說明
屬性名 | 類型 | 說明 |
---|---|---|
shadowColor | color | 陰影渲染顏色 |
shadowRadius | dimension | 背景圓角半徑(0為矩形) |
blurRadius | dimension | 模糊半徑 |
xOffset | dimension | 水平位移 |
yOffset | dimension | 豎直位移 |
bgColor | color | 背景色 |
代碼設置
也可通過代碼設置陰影屬性:
1 shadowLayout.getShadowConfig() //獲取配置類 2 . setBlurRadius(blurRadius) //設置模糊半徑 3 .setXOffset(xoffset) //設置水平位移,最大為20dp 4 .setYOffset(yoffset) //設置豎直位移,最大為20dp 5 .setShadowRadius(shadowRadius) //設置圓角半徑,為0時不是圓角 6 .setShadowColor(shadowColor) //設置陰影顏色 7 .commit(); //生效修改