Android创建引导时的镂空View漏空view

发布时间 2023-12-22 14:08:37作者: 野生野鸡码农

 

import android.graphics.RectF
import android.view.View
import android.view.ViewGroup

object MyGuideUtil {
    /**
     * @baseView 在哪个view基础上进行镂空
     */
    fun guideMain(baseView: View) {
        val location = IntArray(2)
        baseView.getLocationInWindow(location)
        //左上角顶点坐标
        val viewX = location[0]
        val viewY = location[1]
        //右下角顶点坐标
        val viewX1 = viewX + baseView.width.toFloat()
        val viewY1 = viewY + baseView.height.toFloat()

        val guideView = MyGuideView(baseView.context).apply {
            reDraw(
                RectF(
                    viewX.toFloat(),
                    viewY.toFloat(),
                    viewX1,
                    viewY1
                )
            )
        }
        /**
         * TODO 在哪个根布局的FrameLayout中增加这个guide
         * 第一种:可以使用activity根布局的实例
         * 第二种:也可以自己建一个全屏的弹窗
         */
        if(baseView.rootView is ViewGroup){
            (baseView.rootView as ViewGroup).apply {
                addView(guideView)
            }
            //TODO 设置“跳过”及其他按钮的位置后再添加进去
            //guideView.root.addView()
        }
    }
}

 

import android.content.Context
import android.graphics.*
import android.view.ViewGroup
import android.widget.FrameLayout

/**
 * 镂空区域绘制 漏空区域绘制
 */
class MyGuideView : FrameLayout {

    constructor(context: Context) : super(context) {
        root = FrameLayout(context)
        addView(root)
        val lp = root.layoutParams
        lp.width = ViewGroup.LayoutParams.MATCH_PARENT
        lp.height = ViewGroup.LayoutParams.MATCH_PARENT
        root.layoutParams = lp
        //禁止镂空区域下层被点击
        root.setOnClickListener { }

        paint = Paint().apply {
            //带渐变的黑色
            color = Color.parseColor("#A9000000")
        }

        path = Path()
        path.fillType = Path.FillType.INVERSE_EVEN_ODD
    }

    override fun dispatchDraw(canvas: Canvas?) {
        canvas?.drawPath(path, paint)
        super.dispatchDraw(canvas)
    }

    //TODO 这个root对象是给外部用的,可以增加“跳过按钮”
    var root: ViewGroup

    private var paint: Paint

    private var path: Path

    /**
     * 重新绘制
     */
    fun reDraw(rectF: RectF) {
        path.reset()
        path.addRoundRect(rectF, 20f, 20f, Path.Direction.CW)

        invalidate()
    }

}