直播视频app源码,自定义可点击可滑动的通用RatingBar

直播视频app源码,自定义可点击可滑动的通用RatingBar实现的相关代码

绘制ratingbar

 

绘制未选中的背景

 

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

 

绘制选中图标

这里bitmap宽度使用starSize + starPadding,配合BitmapShader的repeat模式,可以方便绘制出高亮的图标

 

1
/**<br> * 选中icon的Bitmap<br> */<br>private val starBitmap: Bitmap by lazy {<br>    val bitmap = Bitmap.createBitmap(starSize + starPadding.toInt(), starSize, Bitmap.Config.ARGB_8888)<br>    val canvas = Canvas(bitmap)<br>    val starDrawable = ContextCompat.getDrawable(context, starDrawable)<br>    starDrawable?.setBounds(0, 0, starSize, starSize)<br>    starDrawable?.draw(canvas)<br>    bitmap<br>}<br>/**<br> * 绘制高亮图标<br> */<br>private fun drawStarDrawable(canvas: Canvas) {<br>    starDrawablePaint.shader = BitmapShader(starBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT)<br>    canvas.drawRect(0f, 0f, getStarProgressWidth(), height.toFloat(), starDrawablePaint)<br>}

 

绘制纯色的选中效果

使用离屏缓冲,纯色矩形与未选中背景相交的地方进行显示。具体使用可以参考扔物线大佬的文章

 

1
/**<br> * 星星纯色画笔<br> */<br>private val starPaint = Paint().apply {<br>    isAntiAlias = true<br>    xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)<br>}<br>canvas?.let {<br>    // xfermode需要使用离屏缓存<br>    val saved = it.saveLayer(null, null)<br>    drawStar(it)<br>    if (starDrawable == -1) {<br>        drawStarBgColor(it)<br>    } else {<br>        drawStarDrawable(it)<br>    }<br>    it.restoreToCount(saved)<br>}<br>/**<br> * 绘制高亮纯颜色<br> */<br>private fun drawStarBgColor(canvas: Canvas) {<br>    canvas.drawRect(0f, 0f, getStarProgressWidth(), height.toFloat(), starPaint)<br>}

 

绘制进度

 

根据type更正显示效果,是取半,取整还是任意取进度。open方法,可以方便修改

 

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

 

点击+滑动

 

点击+滑动就是重写onTouchEvent事件:

 

1
判断点击位置是否在范围内<br>/**<br> * 点击的point是否在view范围内<br> */<br>private fun pointInView(x: Float, y: Float): Boolean {<br>    return Rect(0, 0, width, height).contains(x.toInt(), y.toInt())<br>}

 

记录按下位置,抬起位置。

 

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

 

滑动记录手指move

 

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

 

以上就是 直播视频app源码,自定义可点击可滑动的通用RatingBar实现的相关代码,更多内容欢迎关注之后的文章

 

posted @   云豹科技-苏凌霄  阅读(186)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示