自定義View-第十四步:setShadowLayer陰影與SetMaskFilter發(fā)光效果

前言

根據(jù)啟艦 的博客所學(xué)習(xí)的自定義View。

一、setShadowLayer構(gòu)造函數(shù)

public void setShadowLayer(float radius, float dx, float dy, int color)  
  • radius:模糊半徑,radius越大越模糊,越小越清晰,但是如果radius設(shè)置為0,則陰影消失不見(jiàn)
  • dx:陰影的橫向偏移距離,正值向右偏移,負(fù)值向左偏移
  • dy:陰影的縱向偏移距離,正值向下偏移,負(fù)值向上偏移
  • color: 繪制陰影的畫(huà)筆顏色,即陰影的顏色(對(duì)圖片陰影無(wú)效)

注意:這里有一點(diǎn)需要非常注意的是setShadowLayer只有文字繪制陰影支持硬件加速,其它都不支持硬件加速,所以為了方便起見(jiàn),我們需要在自定義控件中禁用硬件加速。

二、實(shí)現(xiàn)對(duì)文本,圖形,Image的陰影效果

void init(){
        setLayerType(LAYER_TYPE_SOFTWARE, null);//對(duì)單獨(dú)的View在運(yùn)行時(shí)階段禁用硬件加速
}
  @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        paint.setColor(Color.RED);
        paint.setStrokeWidth(2);
        paint.setAntiAlias(true);
        paint.setTextSize(50);
        paint.setShadowLayer(5, 15, 20, Color.GREEN);
        canvas.drawText("demo", 100, 100, paint);
        canvas.drawCircle(200, 200, 50, paint);
        canvas.drawBitmap(bitmap, null, new RectF(200, 300, 200 + bitmap.getWidth(), 300 + bitmap.getHeight()), paint);
    }
效果圖

三、 清除與顯示陰影

  • 顯示陰影就調(diào)用paint.setShadowLayer方法
  • 清除陰影就調(diào)用paint.clearShadowLayer()

四、TextView及其派生類(lèi)使用ShadowLayer添加陰影效果

直接上代碼??

<TextView  
       …………  
        android:shadowRadius="3"  
        android:shadowDx="5"  
        android:shadowDy="5"  
        android:shadowColor="@android:color/darker_gray"/>  

或者

TextView tv = (TextView)findViewById(R.id.tv);  
tv.setShadowLayer(2,5,5, Color.GREEN);  

五、SetMaskFilter之BlurMaskFilter實(shí)現(xiàn)發(fā)光效果

與setShadowLayer一樣,發(fā)光效果也是使用的高斯模糊,并且只會(huì)影響邊緣部分圖像,內(nèi)部圖像是不受影響的
發(fā)光效果是無(wú)法指定發(fā)光顏色的,采用邊緣部分的顏色取樣來(lái)進(jìn)行模糊發(fā)光。所以邊緣是什么顏色,發(fā)出的光也就是什么顏色的。

1. 基本方法

public MaskFilter setMaskFilter(MaskFilter maskfilter)  
public BlurMaskFilter(float radius, Blur style)  
  • float radius:用來(lái)定義模糊半徑,同樣是高斯模糊算法。
  • Blur style:發(fā)光樣式,有內(nèi)發(fā)光、外發(fā)光、和內(nèi)外發(fā)光,分別對(duì)應(yīng):Blur.INNER(內(nèi)發(fā)光)、Blur.SOLID(外發(fā)光)、Blur.NORMAL(內(nèi)外發(fā)光)、Blur.OUTER(僅發(fā)光部分可見(jiàn)),
void init(){
......
        setLayerType(LAYER_TYPE_SOFTWARE, null);//對(duì)單獨(dú)的View在運(yùn)行時(shí)階段禁用硬件加速
}
 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.BLACK);
        canvas.drawText("正常",30,100,paint);
        Paint paint1 = new Paint();
        paint1.setColor(Color.RED);
        paint1.setStyle(Paint.Style.FILL);
        canvas.drawCircle(300, 100, 50, paint1);

        canvas.drawText("INNER",0,250,paint);
        Paint paint2 = new Paint();
        paint2.setColor(Color.RED);
        paint2.setStyle(Paint.Style.FILL);
        paint2.setMaskFilter(new BlurMaskFilter(50, BlurMaskFilter.Blur.INNER));
        canvas.drawCircle(300, 250, 50, paint2);

        canvas.drawText("OUTER",0,400,paint);
        Paint paint3 = new Paint();
        paint3.setColor(Color.RED);
        paint3.setStyle(Paint.Style.FILL);
        paint3.setMaskFilter(new BlurMaskFilter(50, BlurMaskFilter.Blur.OUTER));
        canvas.drawCircle(300, 400, 50, paint3);

        canvas.drawText("NORMAL",0,550,paint);
        Paint paint4 = new Paint();
        paint4.setColor(Color.RED);
        paint4.setStyle(Paint.Style.FILL);
        paint4.setMaskFilter(new BlurMaskFilter(50, BlurMaskFilter.Blur.NORMAL));
        canvas.drawCircle(300, 550, 50, paint4);
    }
效果圖

2. 圖片發(fā)光
其實(shí)實(shí)現(xiàn)方式和上邊的一樣的,不過(guò),這里我們先說(shuō)一個(gè)小知識(shí)** extraAlpha()函數(shù)**:

extractAlpha()新建一張僅具有Alpha值的空白圖像
這張圖像的顏色,是由canvas.drawBitmap時(shí)的畫(huà)筆指定的。

舉個(gè)栗子:

void init(){
......
        setLayerType(LAYER_TYPE_SOFTWARE, null);//對(duì)單獨(dú)的View在運(yùn)行時(shí)階段禁用硬件加速
}
  //初始化
    private void initBitmap() {
        bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.bear);
        mBitmap = bitmap.extractAlpha();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.BLACK);
        paint.setColor(Color.GREEN);
        canvas.drawBitmap(mBitmap, null, new RectF(100, 100, 100 + mBitmap.getWidth(), mBitmap.getHeight() + 100), paint);

        canvas.drawBitmap(bitmap, null, new RectF(100, 300, 100 + bitmap.getWidth(), bitmap.getHeight() + 300), paint);
    }
效果圖

那么,接下來(lái)我們就將這兩個(gè)圖發(fā)光吧!
其實(shí)還是這兩句話(huà),哈哈

    mPaint.setColor(mShadowColor);//設(shè)置發(fā)光的顏色
    mPaint.setMaskFilter(new BlurMaskFilter(mRadius, BlurMaskFilter.Blur.NORMAL));//設(shè)置發(fā)光樣式,NORMAL是內(nèi)外發(fā)光

具體源碼:

       setLayerType(LAYER_TYPE_SOFTWARE, null);//對(duì)單獨(dú)的View在運(yùn)行時(shí)階段禁用硬件加速

        paint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.NORMAL));
        paint.setColor(Color.GREEN);
        canvas.drawBitmap(mBitmap, null, new RectF(100, 100, 100 + mBitmap.getWidth(), mBitmap.getHeight() + 100), paint);

        paint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.NORMAL));
        canvas.drawBitmap(bitmap, null, new RectF(100, 300, 100 + bitmap.getWidth(), bitmap.getHeight() + 300), paint);

效果圖為【可以對(duì)比上面未發(fā)光的效果圖】:

BlurMaskFilter

后記

由于作者君偷懶,所以paint的創(chuàng)建呀什么的,全都放在onDraw里面了,大家寫(xiě)代碼的時(shí)候,要使onDraw輕量。不要直接放進(jìn)去,在外面初始化哈~
感謝大家提出的問(wèn)題,筆芯~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容