直播视频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实现的相关代码,更多内容欢迎关注之后的文章
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现