短视频开发app,自定义带进度条的视频播放按钮
短视频开发app,自定义带进度条的视频播放按钮
具体的代码逻辑都有清楚的注释,可以直接查看代码
1 | <br> public class MusicProgress extends View {<br> private Context mContext;<br> private static final int DEFAULT_SIZE = 40;<br> private static final float HALF = 0.5f;<br> private static final float ONE_TENTH = 0.1f;<br> private static final float DEFAULT_START_ANGLE = -90;<br> private int defaultSize;<br> private int mWidth;<br> private int mHeight;<br> private Paint mBgPaint;<br> private Paint mProgressPaint;<br> // 背景颜色和进度条颜色<br> private int mBgColor;<br> private int mProgressColor;<br> // 背景圆<br> private int radius;<br> private int circlePoint;<br> // 播放暂停按钮<br> private Bitmap mPlayBm;<br> private Bitmap mPauseBm;<br> private Bitmap mBitmap;<br> private Rect mDstRect;<br> private int mBmOffset;<br> // 进度条<br> private RectF mProgressRectF;<br> private int mProgressWidth;<br> // 进度条开始结束角度<br> private float mStartAngle;<br> private float mSweepAngle;<br> public MusicProgress(Context context) {<br> this(context, null);<br> }<br> public MusicProgress(Context context,<br> @Nullable AttributeSet attrs) {<br> this(context, attrs, 0);<br> }<br> public MusicProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {<br> super(context, attrs, defStyleAttr);<br> this.mContext = context;<br> init();<br> }<br> private void init() {<br> defaultSize = dp2px(DEFAULT_SIZE);<br> mProgressWidth = (int) (defaultSize * ONE_TENTH);<br> radius = (int) (defaultSize * HALF - mProgressWidth * HALF);<br> circlePoint = (int) (defaultSize * HALF);<br> mBgColor = ContextCompat.getColor(mContext, R.color.progress_bg_color);<br> mProgressColor = ContextCompat.getColor(mContext, R.color.progress_color);<br> // 暂停、播放按钮的绘制区域<br> mBmOffset = (int) (defaultSize * HALF * HALF);<br> mDstRect = new Rect(mBmOffset, mBmOffset,<br> defaultSize - mBmOffset, defaultSize - mBmOffset);<br> mPlayBm = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.play);<br> mPauseBm = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.pause);<br> // 默认是暂停状态<br> mBitmap = mPlayBm;<br> mBgPaint = new Paint();<br> mBgPaint.setAntiAlias(true);<br> mBgPaint.setColor(mBgColor);<br> mProgressPaint = new Paint();<br> mProgressPaint.setAntiAlias(true);<br> mProgressPaint.setColor(mProgressColor);<br> mProgressPaint.setStrokeWidth(mProgressWidth);<br> mProgressPaint.setStyle(Paint.Style.STROKE);<br> // 进度条<br> mProgressRectF = new RectF(0, 0, defaultSize, defaultSize);<br> this.mStartAngle = DEFAULT_START_ANGLE;<br> }<br> @Override<br> protected void onSizeChanged(int w, int h, int oldw, int oldh) {<br> super.onSizeChanged(w, h, oldw, oldh);<br> this.mWidth = w;<br> this.mHeight = h;<br> if (mWidth > 0) {<br> // 修改进度条宽度<br> mProgressWidth = (int) (mWidth * ONE_TENTH);<br> mProgressPaint.setStrokeWidth(mProgressWidth);<br> // 修改背景圆的半径<br> radius = (int) (mWidth * HALF - mProgressWidth * HALF);<br> // 修改圆心<br> circlePoint = (int) (mWidth * HALF);<br> // 暂停、播放按钮的绘制区域<br> mBmOffset = (int) (mWidth * HALF * HALF);<br> mDstRect = new Rect(mBmOffset, mBmOffset,<br> mWidth - mBmOffset, mWidth - mBmOffset);<br> float size = mWidth - mProgressWidth * HALF;<br> // 进度条<br> mProgressRectF = new RectF(mProgressWidth * HALF, mProgressWidth * HALF, size, size);<br> }<br> }<br> @Override<br> protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {<br> super.onMeasure(widthMeasureSpec, heightMeasureSpec);<br> setMeasuredDimension(getSize(widthMeasureSpec), getSize(heightMeasureSpec));<br> }<br> /**<br> * 获取测量大小<br> */<br> private int getSize(int measureSpec) {<br> int result;<br> int specMode = MeasureSpec.getMode(measureSpec);<br> int specSize = MeasureSpec.getSize(measureSpec);<br> if (specMode == MeasureSpec.EXACTLY) {<br> //确切大小,所以将得到的尺寸给view<br> result = specSize;<br> } else if (specMode == MeasureSpec.AT_MOST) {<br> //默认值为40dp, 此处要结合父控件给子控件的最多大小(要不然会填充父控件),所以采用最小值<br> result = Math.min(defaultSize, specSize);<br> } else {<br> result = defaultSize;<br> }<br> return result;<br> }<br> @Override<br> protected void onDraw(Canvas canvas) {<br> super.onDraw(canvas);<br> // 绘制背景圆<br> canvas.drawCircle(circlePoint, circlePoint, radius, mBgPaint);<br> // 绘制播放暂停按钮<br> canvas.drawBitmap(mBitmap, null, mDstRect, mBgPaint);<br> // 绘制进度条<br> canvas.drawArc(mProgressRectF, mStartAngle, mSweepAngle, false, mProgressPaint);<br> }<br> /**<br> * 刷新播放UI.<br> */<br> public void play() {<br> mBitmap = mPauseBm;<br> invalidate();<br> }<br> /**<br> * 刷新暂停UI.<br> */<br> public void pause() {<br> mBitmap = mPlayBm;<br> invalidate();<br> }<br> /**<br> * 更新进度.<br> *<br> * @param startAngle 开始角度<br> * @param sweepAngle 扫过角度<br> */<br> public void updateProgress(@FloatRange(from = -360f, to = 360f) float startAngle,<br> @FloatRange(from = 0f, to = 360f) float sweepAngle) {<br> this.mStartAngle = startAngle;<br> this.mSweepAngle = sweepAngle;<br> invalidate();<br> }<br> /**<br> * 更新进度.<br> *<br> * @param sweepAngle 扫过角度<br> */<br> public void updateProgress(@FloatRange(from = 0f, to = 360f) float sweepAngle) {<br> this.mSweepAngle = sweepAngle;<br> invalidate();<br> }<br> private int dp2px(final float dp) {<br> final float density = mContext.getResources().getDisplayMetrics().density;<br> return (int) (dp * density + 0.5f);<br> }<br> private int px2dp(final float px) {<br> float scale = mContext.getResources().getDisplayMetrics().scaledDensity;<br> return (int) (px / scale + 0.5f);<br> }<br>} |
涉及的资源文件
1 | <br><color name= "progress_bg_color" >#7A7A7A</color><br><color name= "progress_color" >#00F1B7</color> |
以上就是短视频开发app,自定义带进度条的视频播放按钮, 更多内容欢迎关注之后的文章
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现