一個kotlin編寫的dialog庫,希望這是你使用的最後一個dialog庫(v1.1.8 功能更新)

七七就是七七發表於2018-11-04

GenjiDialog

基於kotlin的通用dialog

最近忙了好幾周,這週末總算花了小半天時間來填一下以前挖的坑。

關於該庫的基本功能請往這邊走:GenjiDialog

本次更新主要新增了MaskView控制元件,能夠用來做使用者引導頁的遮罩層,目前支援一個高亮區域,之後如果又需要,則會改良為可顯示多個高亮區域。

先配圖

一個kotlin編寫的dialog庫,希望這是你使用的最後一個dialog庫(v1.1.8 功能更新)

如圖,這是一個很簡單的遮罩+高亮區域,你可以在上面佈局任意的提示語或提示圖

用法如下

 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支援一下,謝謝!

相關文章