• 當前位置:首頁 > IT技術 > 移動平臺 > 正文

    直播視頻app源碼,自定義可點擊可滑動的通用RatingBar
    2021-09-15 15:07:45

    直播視頻app源碼,自定義可點擊可滑動的通用RatingBar實現的相關代碼

    繪制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
    }
    /**
    ?* 繪制星星默認未選中背景
    ?*/
    private fun drawStar(canvas: Canvas) {
    ? ? for (i in 0 until starCount) {
    ? ? ? ? val starLeft = i * (starSize + starPadding)
    ? ? ? ? canvas.drawBitmap(starBgBitmap, starLeft, 0f, starBgPaint)
    ? ? }
    }

    ?

    繪制選中圖標

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

    ?

    /**
    ?* 選中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
    }
    /**
    ?* 繪制高亮圖標
    ?*/
    private fun drawStarDrawable(canvas: Canvas) {
    ? ? starDrawablePaint.shader = BitmapShader(starBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT)
    ? ? canvas.drawRect(0f, 0f, getStarProgressWidth(), height.toFloat(), starDrawablePaint)
    }

    ?

    繪制純色的選中效果

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

    ?

    /**
    ?* 星星純色畫筆
    ?*/
    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)
    }

    ?

    繪制進度

    ?

    根據type更正顯示效果,是取半,取整還是任意取進度。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
    ? ? ? ? }
    ? ? }
    }
    /**
    ?* 取整規則
    ?*/
    private fun ceilWhole(x: Float): Float {
    ? ? return ceil(x)
    }
    /**
    ?* 取半規則
    ?*/
    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
    ? ? }
    }

    ?

    點擊+滑動

    ?

    點擊+滑動就是重寫onTouchEvent事件:

    ?

    判斷點擊位置是否在范圍內
    /**
    ?* 點擊的point是否在view范圍內
    ?*/
    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)
    ? ? }
    }

    ?

    滑動記錄手指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源碼,自定義可點擊可滑動的通用RatingBar實現的相關代碼,更多內容歡迎關注之后的文章

    ?

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

    開通會員,享受整站包年服務
    国产呦精品一区二区三区网站|久久www免费人咸|精品无码人妻一区二区|久99久热只有精品国产15|中文字幕亚洲无线码