當(dāng)前位置:首頁(yè) > IT技術(shù) > 移動(dòng)平臺(tái) > 正文

直播視頻app源碼,自定義可點(diǎn)擊可滑動(dòng)的通用RatingBar
2021-09-15 15:07:45

直播視頻app源碼,自定義可點(diǎn)擊可滑動(dòng)的通用RatingBar實(shí)現(xiàn)的相關(guān)代碼

繪制ratingbar

?

繪制未選中的背景

?

/**
?* 未選中Bitmap
?*/
private val starBgBitmap: Bitmap by lazy {
? ? val bitmap = Bitmap.createBitmap(starSize, starSize, Bitmap.Config.ARGB_8888)
? ? val canvas = Canvas(bitmap)
? ? val starDrawable = ContextCompat.getDrawable(context, starBgDrawable)
? ? starDrawable?.setBounds(0, 0, starSize, starSize)
? ? starDrawable?.draw(canvas)
? ? bitmap
}
/**
?* 繪制星星默認(rèn)未選中背景
?*/
private fun drawStar(canvas: Canvas) {
? ? for (i in 0 until starCount) {
? ? ? ? val starLeft = i * (starSize + starPadding)
? ? ? ? canvas.drawBitmap(starBgBitmap, starLeft, 0f, starBgPaint)
? ? }
}

?

繪制選中圖標(biāo)

這里bitmap寬度使用starSize + starPadding,配合BitmapShader的repeat模式,可以方便繪制出高亮的圖標(biāo)

?

/**
?* 選中icon的Bitmap
?*/
private val starBitmap: Bitmap by lazy {
? ? val bitmap = Bitmap.createBitmap(starSize + starPadding.toInt(), starSize, Bitmap.Config.ARGB_8888)
? ? val canvas = Canvas(bitmap)
? ? val starDrawable = ContextCompat.getDrawable(context, starDrawable)
? ? starDrawable?.setBounds(0, 0, starSize, starSize)
? ? starDrawable?.draw(canvas)
? ? bitmap
}
/**
?* 繪制高亮圖標(biāo)
?*/
private fun drawStarDrawable(canvas: Canvas) {
? ? starDrawablePaint.shader = BitmapShader(starBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT)
? ? canvas.drawRect(0f, 0f, getStarProgressWidth(), height.toFloat(), starDrawablePaint)
}

?

繪制純色的選中效果

使用離屏緩沖,純色矩形與未選中背景相交的地方進(jìn)行顯示。具體使用可以參考扔物線大佬的文章

?

/**
?* 星星純色畫筆
?*/
private val starPaint = Paint().apply {
? ? isAntiAlias = true
? ? xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
}
canvas?.let {
? ? // xfermode需要使用離屏緩存
? ? val saved = it.saveLayer(null, null)
? ? drawStar(it)
? ? if (starDrawable == -1) {
? ? ? ? drawStarBgColor(it)
? ? } else {
? ? ? ? drawStarDrawable(it)
? ? }
? ? it.restoreToCount(saved)
}
/**
?* 繪制高亮純顏色
?*/
private fun drawStarBgColor(canvas: Canvas) {
? ? canvas.drawRect(0f, 0f, getStarProgressWidth(), height.toFloat(), starPaint)
}

?

繪制進(jìn)度

?

根據(jù)type更正顯示效果,是取半,取整還是任意取進(jìn)度。open方法,可以方便修改

?

/**
?* 獲取星星繪制寬度
?*/
private fun getStarProgressWidth(): Float {
? ? val percent = progress / 100f
? ? val starDrawCount = percent * starCount
? ? return when (starType) {
? ? ? ? StarType.HALF.ordinal -> {
? ? ? ? ? ? ceilHalf(starDrawCount) * starSize + starDrawCount.toInt() * starPadding
? ? ? ? }
? ? ? ? StarType.WHOLE.ordinal -> {
? ? ? ? ? ? ceilWhole(starDrawCount) * starSize + starDrawCount.toInt() * starPadding
? ? ? ? }
? ? ? ? else -> {
? ? ? ? ? ? starDrawCount * starSize + starDrawCount.toInt() * starPadding
? ? ? ? }
? ? }
}
/**
?* 取整規(guī)則
?*/
private fun ceilWhole(x: Float): Float {
? ? return ceil(x)
}
/**
?* 取半規(guī)則
?*/
private fun ceilHalf(x: Float): Float {
? ? // 四舍五入 1.3->1+0.5->1.5 1.7->2
? ? val round = round(x)
? ? return when {
? ? ? ? round < x -> round + 0.5f
? ? ? ? round > x -> round
? ? ? ? else -> x
? ? }
}

?

點(diǎn)擊+滑動(dòng)

?

點(diǎn)擊+滑動(dòng)就是重寫onTouchEvent事件:

?

判斷點(diǎn)擊位置是否在范圍內(nèi)
/**
?* 點(diǎn)擊的point是否在view范圍內(nèi)
?*/
private fun pointInView(x: Float, y: Float): Boolean {
? ? return Rect(0, 0, width, height).contains(x.toInt(), y.toInt())
}

?

記錄按下位置,抬起位置。

?

MotionEvent.ACTION_DOWN -> {
? ? downX = event.x
? ? downY = event.y
}
MotionEvent.ACTION_UP -> {
? ? if (starClickable && abs(event.y - downY) <= touchSlop && abs(event.x - downX) <= touchSlop && pointInView(event.x, event.y)) {
? ? ? ? parent.requestDisallowInterceptTouchEvent(true)
? ? ? ? val progress = (event.x / width * 100).toInt()
? ? ? ? setProgress(progress)
? ? ? ? listener?.onClickProgress(progress)
? ? } else {
? ? ? ? parent.requestDisallowInterceptTouchEvent(false)
? ? }
}

?

滑動(dòng)記錄手指move

?

MotionEvent.ACTION_MOVE -> {
? ? if (starScrollable && abs(event.x - downX) - abs(event.y - downY) >= touchSlop && pointInView(event.x, event.y)) {
? ? ? ? parent.requestDisallowInterceptTouchEvent(true)
? ? ? ? val progress = (event.x / width * 100).toInt()
? ? ? ? setProgress(progress)
? ? ? ? listener?.onScrollProgress(progress)
? ? } else {
? ? ? ? parent.requestDisallowInterceptTouchEvent(false)
? ? }
}

?

以上就是 直播視頻app源碼,自定義可點(diǎn)擊可滑動(dòng)的通用RatingBar實(shí)現(xiàn)的相關(guān)代碼,更多內(nèi)容歡迎關(guān)注之后的文章

?

本文摘自 :https://www.cnblogs.com/

開通會(huì)員,享受整站包年服務(wù)立即開通 >