效果图

安卓自定义View实现刮刮卡_ide

代码

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​