日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android 图片圆角 遮罩_Android 自定义View练手Demo(一)实现圆角遮罩效果

發布時間:2025/4/5 Android 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 图片圆角 遮罩_Android 自定义View练手Demo(一)实现圆角遮罩效果 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Android 自定義View系列文章

Android自定義View實現圓角遮罩效果

一圖勝千言,有一個遮罩就會凸顯出重點區域

1-1.jpg

本文通過兩種方式來實現這種效果,來達到自定義View練手的效果

此效果的用途

在裁剪圖片,確定裁剪范圍

在APP中引導用戶,突顯某個區域

這是一個麻雀雖小五臟俱全的小Demo了,非常適合練手。

1.引言

通過本文可以學習到

Canvas和Paint 的常用且實用的 API

Xfermode的使用

View級別的離屏緩沖的開啟方式

Canvas的離屏緩沖和View的離屏緩沖的區別

如何給自定義View設置自定義屬性的使用

2.第一種實現方式

class RoundRectCoverView(context: Context, attrs: AttributeSet) : View(context, attrs) {

private val paint = Paint(Paint.ANTI_ALIAS_FLAG)

private var mPadding = 40.dp //間距

private var mRoundCorner = 10.dp //圓角矩形的角度

private var mCoverColor = "#99000000".toColorInt()//遮罩的顏色

private val porterDuffXfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_OUT)

init {

//開啟View級別的離屏緩沖,并關閉硬件加速,使用軟件繪制

setLayerType(LAYER_TYPE_SOFTWARE, null)

}

override fun onDraw(canvas: Canvas) {

//先畫一個圓角矩形,也就是透明區域(Destination image)

canvas.drawRoundRect(mPadding, mPadding, width - mPadding, height - mPadding, mRoundCorner, mRoundCorner, paint)

//設置遮罩的顏色

paint.color = mCoverColor

//設置paint的 xfermode 為PorterDuff.Mode.SRC_OUT

paint.xfermode = porterDuffXfermode

//畫遮罩的矩形(Source image)

canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint)

//清空paint 的 xfermode

paint.xfermode = null

}

上面代碼中的注釋已經寫的很清楚了,這里說一下 setLayerType(LAYER_TYPE_SOFTWARE, null) 是開啟View級別的離屏緩沖,就是拿出整個View大小的一塊區域,這塊區域是透明的。那么你就可能會好奇,為啥要拿出這么一塊透明的區域呢?因為使用PorterDuff.Mode時候需要用到。

這里面我們用到的是PorterDuff.Mode.SRC_OUT,正好對應的是Source Out這種模式是我們想要的

注意Destination image是第一次畫的圓角矩形,需要畫在一個透明的View中,這就需要離屏緩沖

Source image是畫的帶顏色的遮罩也就是整個View

PorterDuff.Mode.SRC_OUT,類似于把后畫的和先前畫的重疊的部分,摳出去扔掉,結果就是我們要的效果

3.第二種實現方式

class RoundRectCoverView(context: Context, attrs: AttributeSet) : View(context, attrs) {

private val paint = Paint(Paint.ANTI_ALIAS_FLAG)

private var mPadding = 40.dp //間距

private var mRoundCorner = 10.dp //圓角矩形的角度

private var mCoverColor = "#99000000".toColorInt()//遮罩的顏色

private val bounds = RectF()

private val porterDuffXfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_OUT)

private val clipPath = Path()

override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {

//設置離屏緩沖的范圍

bounds.set(0f, 0f, width.toFloat(), height.toFloat())

//設置Clip Path的矩形區域

clipPath.addRoundRect(mPadding, mPadding, width - mPadding, height - mPadding, mRoundCorner, mRoundCorner, Path.Direction.CW)

}

override fun onDraw(canvas: Canvas) {

//Canvas的離屏緩沖

val count = canvas.saveLayer(bounds, paint)

//KTX的擴展函數相當于對Canvas的 save 和 restore 操作

canvas.withSave {

//畫遮罩的顏色

canvas.drawColor(mCoverColor)

//按Path來裁切

canvas.clipPath(clipPath)

//畫鏤空的范圍

canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.SRC)

}

//把離屏緩沖的內容,繪制到View上去

canvas.restoreToCount(count)

}

}

解釋一下,在onSizeChanged方法中,我們設置了離屏緩沖的范圍,注意這個范圍夠用就行,太大了耗費性能。同時設置了Clip Path裁剪的矩形區域。

onDraw方法中

首先開啟離屏緩沖(注意這里開啟的是Canvas的離屏緩沖)這范圍就是bounds的范圍

畫出完整的遮罩的顏色

然后把Canvas裁切出一個圓角矩形

然后在話一個透明的顏色,模式指定為PorterDuff.Mode.SRC

把離屏緩沖的內容,繪制到View上去

注意:記得開離屏緩沖,否則結果可能不是你想要的

4.設置自定義屬性

4.1首先在values文件夾下,創建一個attrs.xml的文件(當然你也可以叫別的名字,但這個是規范)

聲明你想再xml中能設置的屬性,比如我這里聲明了,圓角的大小,圓角矩形的padding值,以及遮罩的顏色

4.2在代碼中動態獲取xml中設置的值

init {

//通過TypeArray 獲取 xml 配置的屬性

val ta = context.obtainStyledAttributes(attrs, R.styleable.RoundRectCoverView)

mPadding = ta.getDimension(R.styleable.RoundRectCoverView_roundPadding, 40.dp)

mRoundCorner = ta.getDimension(R.styleable.RoundRectCoverView_roundCorner, 10.dp)

mCoverColor = ta.getColor(R.styleable.RoundRectCoverView_roundCoverColor, "#99000000".toColorInt())

ta.recycle()

}

通過TypeArray獲取,聲明的屬性值

賦值給成員變量,下面使用的時候就直接使用了

回收TypeArray

4.3在xml代碼直接使用

xmlns:app="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="match_parent">

android:layout_width="0dp"

android:layout_height="0dp"

android:src="@drawable/captain_america"

android:scaleType="centerCrop"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintLeft_toLeftOf="parent"

app:layout_constraintRight_toRightOf="parent"

app:layout_constraintTop_toTopOf="parent" />

android:layout_width="0dp"

android:layout_height="0dp"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintLeft_toLeftOf="parent"

app:layout_constraintRight_toRightOf="parent"

app:layout_constraintTop_toTopOf="parent"

app:roundCorner="10dp"//角度

app:roundCoverColor="#aa000000"//遮罩顏色

app:roundPadding="30dp" />

5.總結

離屏緩沖的兩種方式區別以及開啟方式

Canvas.saveLayer() 可以做短時的離屏緩沖,Google不建議使用,因為每次繪制都需要拿出一塊來,耗費性能

View.setLayerType()是直接把整個 View 都繪制在離屏緩沖中,Google建議這樣做。setLayerType(LAYER_TYPE_HARDWARE) 是使用 GPU 來緩沖, setLayerType(LAYER_TYPE_SOFTWARE) 是直接直接用一個 Bitmap 來緩沖。

PorterDuff.Mode的類型,已經使用,需要有透明的背景色

自定義屬性的方式

這是一個簡單且使用的Demo,很適合練手!

6.源碼地址

總結

以上是生活随笔為你收集整理的android 图片圆角 遮罩_Android 自定义View练手Demo(一)实现圆角遮罩效果的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。