android新手功能引导高亮抠图

5 阅读1分钟


import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.PorterDuff
import android.graphics.PorterDuffXfermode
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import kotlin.math.min

class FeatureGuideMaskView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
) : View(context, attrs) {

    private val dimPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = 0x99000000.toInt()
        style = Paint.Style.FILL
    }
    private val clearPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
    }
    private val spotlightRect: RectF = RectF()

    private var type: FeatureGuidePopupType = FeatureGuidePopupType.CoinHub
    private var customSpotlightRect: RectF? = null
    private var customSpotlightCornerRadiusPx: Float = 0f

    init {
        setLayerType(LAYER_TYPE_SOFTWARE, null)
    }

    fun setType(type: FeatureGuidePopupType) {
        this.type = type
        if (type != FeatureGuidePopupType.CoinHub && type != FeatureGuidePopupType.CoinBox) {
            customSpotlightRect = null
        }
        invalidate()
    }

    fun setCustomSpotlightRect(spotlightRect: RectF, cornerRadiusPx: Float) {
        customSpotlightRect = RectF(spotlightRect)
        customSpotlightCornerRadiusPx = cornerRadiusPx
        invalidate()
    }

    fun clearCustomSpotlightRect() {
        customSpotlightRect = null
        invalidate()
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), dimPaint)
        val widthPx: Float = width.toFloat()
        val heightPx: Float = height.toFloat()
        when (type) {
            FeatureGuidePopupType.SendToChat -> {
                // Bottom attach strip highlight for CoinHub attachment flow only
                val horizontalPaddingPx: Float = dpToPx(11f)
                val spotlightHeightPx: Float = dpToPx(53f)
                val bottomOffsetPx: Float = dpToPx(12f)
                val cornerRadiusPx: Float = dpToPx(10f)
                val left: Float = horizontalPaddingPx
                val right: Float = widthPx - horizontalPaddingPx
                val top: Float = heightPx - spotlightHeightPx - bottomOffsetPx
                val bottom: Float = heightPx - bottomOffsetPx
                spotlightRect.set(left, top.coerceAtLeast(dpToPx(12f)), right, bottom)
                canvas.drawRoundRect(spotlightRect, cornerRadiusPx, cornerRadiusPx, clearPaint)
            }

            FeatureGuidePopupType.CoinHub -> {
                val rect: RectF? = customSpotlightRect
                if (rect != null) {
                    val cornerRadiusPx: Float = min(customSpotlightCornerRadiusPx, rect.height() / 2f)
                    canvas.drawRoundRect(rect, cornerRadiusPx, cornerRadiusPx, clearPaint)
                }
            }

            FeatureGuidePopupType.CoinBox -> {
                val rect: RectF? = customSpotlightRect
                if (rect != null) {
                    val cornerRadiusPx: Float = min(customSpotlightCornerRadiusPx, rect.height() / 2f)
                    canvas.drawRoundRect(rect, cornerRadiusPx, cornerRadiusPx, clearPaint)
                }
            }

            FeatureGuidePopupType.CoinHubTicker,
            FeatureGuidePopupType.Manage -> Unit
        }
    }

    private fun dpToPx(dp: Float): Float {
        return dp * resources.displayMetrics.density
    }
}