GenjiDialog
基於kotlin的通用dialog
最近忙了好幾周,這週末總算花了小半天時間來填一下以前挖的坑。
關於該庫的基本功能請往這邊走:GenjiDialog
本次更新主要新增了MaskView控制元件,能夠用來做使用者引導頁的遮罩層,目前支援一個高亮區域,之後如果又需要,則會改良為可顯示多個高亮區域。
先配圖
如圖,這是一個很簡單的遮罩+高亮區域,你可以在上面佈局任意的提示語或提示圖
用法如下
newGenjiDialog {
layoutId = R.layout.dialog_mask
dimAmount = 0f
isFullHorizontal = true
isFullVerticalOverStatusBar = true
gravity = DialogGravity.CENTER_CENTER
animStyle = R.style.AlphaEnterExitAnimation
convertListenerFun { holder, dialog ->
holder.getView<MaskView>(R.id.maskView)?.apply {
this.highlightArea = HighlightArea(RectF(
this@MaskViewActivity.btn.left.toFloat(),
this@MaskViewActivity.btn.top.toFloat(),
this@MaskViewActivity.btn.right.toFloat(),
this@MaskViewActivity.btn.bottom.toFloat()))
}
}
}.showOnWindow(supportFragmentManager)
複製程式碼
其實就是設定高亮區域的位置以及寬高而已,原始碼也很簡單。
原始碼
class MaskView : View {
private var paint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)
//MaskView的實際寬高
private var trueWidth = 0
private var trueHeight = 0
//高亮區域型別
private var highlightAreaType = HighlightAreaType.TRANSPARENT_CUBE
//高亮區域屬性
var highlightArea = HighlightArea()
set(value) {
field = value
invalidate()
}
//高亮區域需要繪製的bitmap
var highlightBitmap: Bitmap? = null
set(value) {
field = value
highlightAreaType = HighlightAreaType.BITMAP
invalidate()
}
//遮罩的透明度,0-1
var maskAlpha = 0.5f
set(value) {
field = value
invalidate()
}
//背景色,固定透明,防止與遮罩層顏色衝突
private var bgColor = Color.TRANSPARENT
//整個view的rect
private val viewFullRect = Rect()
//混合模式
private val xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OUT)
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
// 載入自定義屬性集合
val a = context.obtainStyledAttributes(attrs, R.styleable.MaskView)
highlightAreaType = when (a.getInt(R.styleable.MaskView_mask_highlightAreaType, HighlightAreaType.TRANSPARENT_CUBE.value)) {
0 -> HighlightAreaType.TRANSPARENT_CUBE
1 -> HighlightAreaType.BITMAP
else -> HighlightAreaType.TRANSPARENT_CUBE
}
highlightArea.areaRect.set(
a.getDimension(R.styleable.MaskView_mask_highlightAreaLeft, 0f),
a.getDimension(R.styleable.MaskView_mask_highlightAreaTop, 0f),
a.getDimension(R.styleable.MaskView_mask_highlightAreaRight, 0f),
a.getDimension(R.styleable.MaskView_mask_highlightAreaBottom, 0f)
)
val radius = a.getDimension(R.styleable.MaskView_mask_highlightAreaRadius, 0f)
highlightArea.radiusX = radius
highlightArea.radiusY = radius
a.getResourceId(R.styleable.MaskView_mask_highlightBitmap, 0).apply {
if (this != 0) {
highlightBitmap = BitmapFactory.decodeResource(resources, this)
}
}
maskAlpha = a.getFloat(R.styleable.MaskView_mask_Alpha, 0.5f)
a.recycle()
}
override fun onDraw(canvas: Canvas) {
//設定背景色-預設透明,防止底色是黑色
setBackgroundColor(bgColor)
//開始離屏渲染
val saved = canvas.saveLayer(
viewFullRect.left.toFloat(),
viewFullRect.top.toFloat(),
viewFullRect.right.toFloat(),
viewFullRect.bottom.toFloat(), paint)
//設定畫筆顏色-遮罩顏色
paint.color = Color.argb((255 * maskAlpha).toInt(), 0, 0, 0)
//在螢幕外繪製遮罩
canvas.drawRect(viewFullRect, paint)
//設定鏤空的顏色-實際上可隨意設定顏色
paint.color = Color.WHITE
//設定影象混合模式,這裡設定的是將新影象與舊影象所重合的位置鏤空
paint.xfermode = xfermode
//在螢幕外繪製需要鏤空的位置
canvas.drawRoundRect(highlightArea.areaRect, highlightArea.radiusX, highlightArea.radiusY, paint)
//關閉混合
paint.xfermode = null
//結束離屏渲染
canvas.restoreToCount(saved)
//如果需要在鏤空位置繪製bitmap
if (highlightAreaType == HighlightAreaType.BITMAP) {
highlightBitmap?.let {
canvas.drawBitmap(
it,
viewFullRect, highlightArea.areaRect, paint)
}
}
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
super.onLayout(changed, left, top, right, bottom)
trueWidth = right - left
trueHeight = bottom - top
//設定遮罩層-大小為該 MaskView 在頁面上的實際大小
viewFullRect.set(0, 0, trueWidth, trueHeight)
}
}
複製程式碼
本文主要簡單的介紹GenjiDialog庫的新功能,所以篇幅不長,第一次瞭解GenjiDialog的朋友可以先看看第一篇文章:GenjiDialog 瞭解其使用方法。
當然也歡迎大家到github為該庫點上一個star支援一下,謝謝!