天天看點

android cardview陰影_最簡單的方式實作自定義陰影效果

網話說UI設計有三寶 :透明,陰影,加圓角。很多UI在做設計的時候都喜歡做卡片形式,然後添加陰影。卡片UI确實挺好看,但是對Android開發者來說,顯示陰影卻并不那麼手到擒來,因為Android對陰影沒有做出很好的支援。

CardView

谷歌也許早就注意到了UI的三寶之一陰影,于是開發了一個繼承FrameLayout的CardView公開發這使用,這個控件雖然在v7包裡,但是需要單獨添加依賴才可以使用,就好像不是親生的似的!

CardView本質上繼承FrameLayout,需要添加依賴才可以使用:

compile 'com.android.support:cardview-v7:25.3.1' 
           

當你知道它繼承FrameLayout的時候你就知道怎麼使用了,但是這個CardView有很多局限性,比如不能修改陰影的顔色,不能修改陰影的深淺。這就很詭異了,根本無法滿足UI設計潮流的内心。

那為了産品蒸蒸日上,早日走上人生巅峰,實作财富自由,應該如何讓你的APP支援修改陰影的顔色呢?

有個很暴力的辦法,就是吧CardView的代碼自己摳出來,然後自己定制,網上已經有很多人這樣做了。

比如這篇CSDN部落客就這樣做了:https://blog.csdn.net/wangjie_de/article/details/82993017

他的思路是修改谷歌原生的CardView代碼:原生的CardView的陰影邏輯分為高版本21以上的和低版本21一下的兩種方案處理,其中低版本使用了漸變色來初六陰影漸變的效果,而高版本使用了 Elevation來設定陰影,但是 Elevation又沒提供修改顔色的方法,是以作者就把高版本的實作方案拿掉了,統一采用低版本的處理方法,就可以修改顔色了。具體過程請看其部落格。

但是現在我自己探索了一個新的較為簡單的添加陰影的實作方案,僅供參考

ShadowCardView

思路:首先要明确陰影的實作思路是什麼,其實就是顔色導緻的視覺錯覺。說白了就是在你的Card周圍畫一個漸變的展現立體感的顔色。

基于上述思路,我們在一個在一個view上畫一個矩形的圖形,讓他周圍有漸變色的陰影即可。于是我們想起幾個API:

  • 類:Paint 用于在Android上畫圖的類,相當于畫筆
  • 類:Canvas 相當于畫布,Android上的view的繪制都與他相關
  • 方法:paint.setShadowLayer可以給繪制的圖形增加陰影,還可以設定陰影的顔色
android cardview陰影_最簡單的方式實作自定義陰影效果

如上圖我們,紅色部分使我們繪制的圖形,邊框以内,紅色之外的是陰影的顯示部分。

有了以上的知識點已經知道可以自己畫陰影了,但是什麼時機開始畫呢?

我們知道谷歌開發的CardView的控件繼承了FrameLayout,友善我們自由擴充。那麼我們也需要繼承FrameLayout。

ShadowCardView繼承FrameLayout之後,可以重寫其一個方法:

@Override 
 protected void dispatchDraw(Canvas canvas) { 
 super.dispatchDraw(canvas); 
    } 
           

這個方法是ViewGroup在繪制子View的時候調用的,那麼我們可以在這個時候進行陰影的繪制。

首先,這個方法已經為我們提供了這個View的畫布:Canvas,我們可以直接在上面進行陰影的繪制,代碼如下:

Paint shadowPaint = new Paint(); 
    shadowPaint.setColor(Color.RED); 
    shadowPaint.setStyle(Paint.Style.FILL); 
    shadowPaint.setAntiAlias(true); 
 float left = 45; 
 float top = 45; 
 float right = getWidth() - 45; 
 float bottom = getHeight() - 45; 
 
    shadowPaint.setShadowLayer(45, 0, 0, getContext().getResources().getColor(R.color.color_000000)); 
    RectF rectF = new RectF(left, top, right, bottom); 
    canvas.drawRoundRect(rectF, 0, 0, shadowPaint); 
    canvas.save();
           
  • 建立畫筆,設定畫筆的顔色,風格
  • 擷取繪畫的範圍:ShadowCard的範圍減去需要的陰影的範圍,假如陰影的寬度為45px,則在ShadowCard内部的45px内進行繪制
  • 給畫筆設定陰影的顔色,陰影的模糊度,模糊度值越大越模糊,且不能為0
  • 建立RectF,最後開始繪畫。

這樣陰影就可以成功繪制了,這個方法代碼量很少,很簡單,也很實用。

android cardview陰影_最簡單的方式實作自定義陰影效果

效果如上圖

為了更好的封裝,我們可以為上面需要的參數進行定制,比如陰影的顔色,陰影的寬度,陰影的上下偏移,陰影的模糊度。

全部代碼:

public 
           

attr.xml

<declare-styleable name="ShadowViewCard"> 
 <!--圓角度--> 
 <attr name="shadowRound" format="dimension" /> 
 <!--陰影的高度--> 
 <attr name="shadowLeftHeight" format="dimension" /> 
 <attr name="shadowTopHeight" format="dimension" /> 
 <attr name="shadowRightHeight" format="dimension" /> 
 <attr name="shadowBottomHeight" format="dimension" /> 
 <!--上方陰影的偏離度--> 
 <attr name="shadowOffsetY" format="dimension" /> 
 <attr name="shadowOffsetX" format="dimension" /> 
 <!--陰影顔色--> 
 <attr name="shadowCardColor" format="color" /> 
 <attr name="shadowColor" format="color" /> 
 <!--陰影顔色模糊度,越大越模糊--> 
 <attr name="shadowRadius" format="integer" /> 
 </declare-styleable> 
           

color.xml

<color name="shadow_default_color">#1a000000</color> 
 <color name="shadow_card_default_color">#ffffff</color>