安卓自定义View实现刮刮卡

效果图

代码

class GuaGuaView(context: Context?, attrs: AttributeSet? = null) : View(context, attrs) {

    /**
     * 记录用户绘制的Path
     */
    private var mPath = Path()

    /**
     * 内存中创建的Canvas
     */
    private lateinit var mCanvas: Canvas

    /**
     * mCanvas绘制内容在其上
     */
    private lateinit var mBitmap: Bitmap

    private var isComplete = false

    /**
     * 绘制线条的Paint,即用户手指绘制Path
     */
    private val mFrontPaint = Paint()
    private val mBackPaint = Paint()
    private val mTextBound = Rect()
    private val mText = "¥100,0000"
    private var mLastX = 0
    private var mLastY = 0
    private fun init() {
        mPath = Path()
        initFrontPaint()
        initBackPaint()
    }

    /**
     * 设置画笔的一些参数
     */
    private fun initFrontPaint() {
        mFrontPaint.color = Color.parseColor("#c0c0c0")
        mFrontPaint.isAntiAlias = true
        mFrontPaint.isDither = true
        mFrontPaint.style = Paint.Style.STROKE
        mFrontPaint.strokeJoin = Paint.Join.ROUND // 圆角
        mFrontPaint.strokeCap = Paint.Cap.ROUND // 圆角
        // 设置画笔宽度
        mFrontPaint.strokeWidth = 50f
    }

    /**
     * 初始化canvas的绘制用的画笔
     */
    private fun initBackPaint() {
        mBackPaint.style = Paint.Style.FILL
        mBackPaint.textScaleX = 2f
        mBackPaint.color = Color.DKGRAY
        mBackPaint.textSize = 50f
        mBackPaint.getTextBounds(mText, 0, mText.length, mTextBound)
    }

    override fun onDraw(canvas: Canvas) {
        // canvas.drawBitmap(mBackBitmap, 0, 0, null);
        // 绘制奖项
        canvas.drawText(
            mText, width / 2 - mTextBound.width() / 2.toFloat(),
            height / 2 + mTextBound.height() / 2.toFloat(), mBackPaint
        )
        if (!isComplete) {
            drawPath()
            canvas.drawBitmap(mBitmap, 0f, 0f, null)
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        val width = measuredWidth
        val height = measuredHeight
        // 初始化bitmap
        mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)

        mCanvas = Canvas(mBitmap)

        // 绘制遮盖层
        // mCanvas.drawColor(Color.parseColor("#c0c0c0"));
        mFrontPaint.style = Paint.Style.FILL
        mCanvas.drawRoundRect(
            RectF(0f, 0f, width.toFloat(), height.toFloat()), 30f, 30f,
            mFrontPaint
        )
        mCanvas.drawBitmap(
            BitmapFactory.decodeResource(
                resources,
                R.drawable.guaguale
            ), null, RectF(0f, 0f, width.toFloat(), height.toFloat()), null
        )
    }


    /**
     * 绘制线条
     */
    private fun drawPath() {
        mFrontPaint.style = Paint.Style.STROKE
        mFrontPaint.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OUT)
        mCanvas.drawPath(mPath, mFrontPaint)
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        val action = event.action
        val x = event.x.toInt()
        val y = event.y.toInt()
        when (action) {
            MotionEvent.ACTION_DOWN -> {
                mLastX = x
                mLastY = y
                mPath.moveTo(mLastX.toFloat(), mLastY.toFloat())
            }
            MotionEvent.ACTION_MOVE -> {
                val dx = abs(x - mLastX)
                val dy = abs(y - mLastY)
                if (dx > 3 || dy > 3) mPath.lineTo(x.toFloat(), y.toFloat())
                mLastX = x
                mLastY = y
            }
            MotionEvent.ACTION_UP -> Thread(mRunnable).start()
        }
        invalidate()
        return true
    }

    /**
     * 统计擦除区域任务
     */
    private val mRunnable: Runnable = object : Runnable {
        private lateinit var mPixels: IntArray
        override fun run() {
            val w = width
            val h = height
            var wipeArea = 0f
            val totalArea = w * h.toFloat()
            val bitmap = mBitmap
            mPixels = IntArray(w * h)
            /**
             * 拿到所有的像素信息
             */
            bitmap.getPixels(mPixels, 0, w, 0, 0, w, h)
            /**
             * 遍历统计擦除的区域
             */
            for (i in 0 until w) {
                for (j in 0 until h) {
                    val index = i + j * w
                    if (mPixels[index] == 0) {
                        wipeArea++
                    }
                }
            }
            /**
             * 根据所占百分比,进行一些操作
             */
            if (wipeArea > 0 && totalArea > 0) {
                val percent = (wipeArea * 100 / totalArea).toInt()
                Log.e("TAG", percent.toString() + "")
                if (percent > 50) {
                    Log.e("TAG", "清除区域达到指定百分比,自动清除")
                    isComplete = true
                    postInvalidate()
                }
            }
        }
    }

    init {
        init()
    }
}

完整源代码

https://gitee.com/cxyzy1/guaguaka

安卓开发入门教程系列汇总

安卓发展历程及前景

安卓发展历程
安卓开发前景展望

初探安卓

安装开发工具
创建第一个安卓工程

开发语言学习

Kotlin语言基础

UI控件学习系列

UI控件_TextView
UI控件_EditText
UI控件_Button
UI控件_ImageView
UI控件_RadioButton
UI控件_CheckBox
UI控件_ProgressBar

关注头条号,第一时间获取最新文章:

你可能感兴趣的:(安卓)