应项目需要我这边要定义一个播放录音的控件,效果如图:

这边先讲一下具体的初版思路吧

1、首先我的思路是复杂的问题简单化,先把这个控件拆分为:上面的刻度和下面的进度条

2、刻度可以根据录音的具体时间来画,下面的进度可以继承SeekBar来实现

3、然后将两个控件的组合在一起放在一个自定义的Relativelayout中,组合成一个控件

先上一下效果动图

下面是上代码时间:

一:首先来画刻度尺的部分

刻度尺的部分是比较简单的这里我自定义了一个控件继承View然后同onDraw来画出这个刻度尺来

如果要画出刻度尺则必须知道自定义控件在屏幕的中位置,下面是获取控件在屏幕中具体位置的方法

下面是获取屏幕宽度的方法
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
windowManager.getDefaultDisplay().getMetrics(dm);
screenWidth = dm.widthPixels;
下面是获取视图绝对坐标和相对坐标的方法
getLocationOnScreen ,计算该视图在全局坐标系中的x,y值,(注意这个值是要从屏幕顶端算起,也就是索包括了通知栏的高度)//获取在当前屏幕内的绝对坐标
getLocationInWindow ,计算该视图在它所在的widnow的坐标x,y值,//获取在整个窗口内的绝对坐标 (不是很理解= =、)
getLeft ,getTop,getBottom,getRight,这一组是获取相对在它父亲里的坐标
如果在Activity的OnCreate()事件输出那些参数,是全为0,要等UI控件都加载完了才能获取到这些。
可在onMeasure中中设置自定义控件的高度
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    int width;
    int height;

    if (heightMode == MeasureSpec.EXACTLY) {height = heightSize;
    } else {height = Math.min(mMinHeight, heightSize);
    }width = widthSize;
    setMeasuredDimension(width, height);
}
控件的宽和高确定好之后接下来就是要画刻度值了,刻度值分为两部分,一部分是水平的横线另一部分是

竖直的竖杠,横线比较简单至于竖线考虑到录音的时间是从一到无穷大的,于是这竖线的部分就需要分一分了

首先是1-6s的时候分别画录取时间加一的竖线,大于6的时候则要将对录音的时间进行三等分或者两等分,把时间分的均匀一点就行了,上面的刻度只是个大概的显示所以尽力做到平均就行了。

线画完之后就要画时间的显示了时间的显示如下

将时间进行等分的处理函数

private int courseTime(int record, int time) {if (record % 6 == 0) {//整除6则返回6的整倍数
        return record / 6 * time;
    } else if (record % 3 == 0) {//整除3
        if (time % 2 == 0) {//三等分的位置
            return (record / 3) * (time / 2);
        } else {//其他的位置
            return ((record / 3) * ((time + 1) / 2) - ((record / 3) * ((time - 1) / 2))) / 2 + ((record / 3) * ((time - 1) / 2));
        }} else if (record % 2 == 0) {//能整除2的数值
        if (time % 3 == 0) {//进行二等分的位置
            return (record / 2) * (time / 3);
        } else {//其他位置
            if ((record / 2) % 3 == 1) {//二等分之后再三等分进行余数的分配
                if (time < 3) {//前半部分的二等分
                    return (record / 2 / 3 * time);
                } else {//后半部分的二等分
                    return (record / 2 + record / 2 / 3 * (time - 3));
                }} else {//同上
                if ((record / 2) % 3 == 2) {if (time < 3) {return (record / 2 / 3 * time + time);
                    } else {return (record / 2 + record / 2 / 3 * (time - 3) + (time - 3));
                    }}}}} else {//质数的分配
        if (time == 0) {return 0;
        } else if (time == 3) {return record / 2;
        } else if (time == 6) {return record;
        } else if (time < 3) {if ((record / 2) % 3 == 1) {return (record / 2 / 3 * time);
            } else if ((record / 2) % 3 == 2) {return (record / 2 / 3 * time + time);
            } else {return record / 2 / 3 * time;
            }} else {if ((record / 2 + 1) % 3 == 1) {return (record / 2 + record / 2 / 3 * (time - 3));
            } else if ((record / 2) % 3 == 2) {return (record / 2 + record / 2 / 3 * (time - 3) + (time - 3));
            } else {return record / 2 + (record / 2 + 1) / 3 * (time - 3);
            }}}return 0;
}
直接获取绘制字符串的宽度
textPaint.measureText(str)
将int值的秒级数转换为时分秒格式
private String getCourseTime(Integer seconds) {int day = seconds / (60 * 60 * 24);//换成天
    int hour = (seconds - (60 * 60 * 24 * day)) / 3600;//总秒数-换算成天的秒数=剩余的秒数    剩余的秒数换算为小时
    int minute = (seconds - 60 * 60 * 24 * day - 3600 * hour) / 60;//总秒数-换算成天的秒数-换算成小时的秒数=剩余的秒数    剩余的秒数换算为分
    int second = seconds - 60 * 60 * 24 * day - 3600 * hour - 60 * minute;//总秒数-换算成天的秒数-换算成小时的秒数-换算为分的秒数=剩余的秒数
    if (hour != 0) {return (hour >= 10 ? hour : "0" + hour) + ":" + (minute >= 10 ? minute : "0" + minute) + ":" + (second >= 10 ? second : "0" + second);
    } else if (minute != 0) {return (minute >= 10 ? minute : "0" + minute) + ":" + (second >= 10 ? second : "0" + second);
    } else {return "00:" + (second >= 10 ? second : "0" + second);
    }
}
然后直接在几道竖线下画平分的时间就行了,至此刻度尺就制作完毕了。

二:接下来就是下面的进度条部分了,这个部分我是继承了SeekBar的自定义View制作的

我们也分为三步

1、首先是红色的游标

把默认的游标去除

android:duplicateParentState="true"
android:thumb="@null"

要画出完整的图标就必须把进度条的背景放大

//设置控件的padding 给提示指示图标留出位置
setPadding(linePadding, (int) Math.ceil(imageHeight) - 30, linePadding, 25);

2、就是进度条的颜色、进度和上面的刻度尺要保持两端相同,我的思路是:①进度条的长度保持和上面的刻度尺长度相同 ②画一个图片来覆盖进度条默认的进度图片 ③画一个半透明的灰色横线来作为进度

rectSeek = this.getProgressDrawable().getBounds();
float bm_x = rectSeek.width() * getProgress() / getMax() + (linePadding - (int) Math.ceil(imageWidth) / 2);

//设置控件的padding 给提示指示图标留出位置
setPadding(linePadding, (int) Math.ceil(imageHeight) - 30, linePadding, 25);

图片使用一个xml格式的shape做的可以添加起始、中部和结尾的颜色

canvas.drawBitmap(seekbarThumbBitmap, 0, (int) Math.ceil(imageHeight) - 28, cursorImagePaint);//绘制假的进度条背景色

canvas.drawLine(0, (int) Math.ceil(imageHeight) - 28, bm_x + (int) Math.ceil(imageWidth) / 2, (int) Math.ceil(imageHeight) - 28, seekbarThumbPaint);

3、下面一个就是画tag的功能了,这个主要就是画一个红色的矩形

根据打印tag的时间来确定红色矩形的位置就可以了

mBarRect.left = getPaddingLeft();
mBarRect.right = getWidth() - getPaddingRight();
//final boolean isLayoutRtl = getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
float cx;
//float cy = getHeight() / 2 - getPaddingBottom() / 2 - 2;
float barRectwidth = mBarRect.width() - 50;
cx = mBarRect.left + barRectwidth* (mMarks.get(i).postion / (float) mDuration);
    //}
    //radius = getResources().getDimension(R.dimen.panit_line_space) / 3;
//canvas.drawCircle(cx, cy, radius, mShapePaint);
    //canvas.drawBitmap(mBitmap, cx, cy, mPaintTag);
canvas.drawRect(cx, (int) Math.ceil(imageHeight) - 28, cx + tagWidth, (int) Math.ceil(imageHeight) - 28 + tagHeight, tagPaint);

至此这个控件就基本结束了,下面就是要合入record的代码中了。

自定义刻度尺进度条总结相关推荐

  1. Java渐变进度条_Android ProgressBar自定义图片进度,自定义渐变色进度条

    java.lang.Object ↳android.view.View ↳android.widget.ProgressBar 直接子类 AbsSeekBar 间接子类 RatingBar, Seek ...

  2. Android自定义圆形进度条

    Android自定义圆形进度条 github地址:https://github.com/opq1289/CircleProgressView 效果图: 无动画: 有动画: 整圆: 切割圆: 具体步骤: ...

  3. Android中用图片自定义一个进度条(实现蒙板效果)

    问题概述 对于进度条我相信大家不陌生,这里我就不再多说什么了.因为这个不是重点.我们要说的是如何去自定义一个不一样的进度条.这里用到两张图片(背景和前景),其实是三张(背景.前景和蒙图).当我们的蒙图 ...

  4. android 自定义背景园,Android 自定义ProgressBar 进度条颜色和背景颜色

    Android 自定义ProgressBar 进度条颜色和背景颜色 首先,在drawable目录下新建文件 personal_center_level_progress_bg.xmlandroid a ...

  5. Android 自定义View,自定义属性--自定义圆形进度条(整理)

    很多的时候,系统自带的View满足不了我们的功能需求,那么我们就需要自定义View来满足我们的需求 自定义View时要先继承View,添加类的构造方法,重写父类View的一些方法,例如onDraw,为 ...

  6. android绘制环形进度_Android动态自定义圆形进度条

    这篇文章主要介绍了Android动态自定义圆形进度条,需要的朋友可以参考下 效果图: A.绘制圆环,圆弧,文本 //1.画圆环 //原点坐标 float circleX = width / 2; fl ...

  7. android自定义带进度条的圆形图片

    前言:在项目听新闻的改版中需要实现环绕圆形新闻图片的进度条功能,作为技术预备工作我就去看了一些网上的相关的原理,做了一个自定义带进度条的圆形图片的demo,并将这个实现写成文章发布出来,谁需要了可以进 ...

  8. 微信小程序进度条样式_详解微信小程序——自定义圆形进度条

    微信小程序 自定义圆形进度条,具体如下: 无图无真相,先上图: 实现思路,先绘制底层的灰色圆圈背景,再绘制上层的蓝色进度条. 代码实现: JS代码: 页面初始化 options为页面跳转所带来的参数 ...

  9. Android自定义半圆进度条 半圆渐变色进度条带指示 半圆开口大小可自由修改

    Android自定义半圆进度条 半圆渐变色进度条带指示 半圆开口大小可自由修改 首先我们来看下效果图 不同的开口大小只需要修改一个参数即可 半圆1: 半圆2: 半圆3: 如果是你想要的效果,就直接滑动 ...

  10. 自定义圆形进度条的实现方式

    如何自定义圆形进度条哪,也就是替换一下进度条的图片而已. 先分析一下,系统对进度条如何定义的: 咱们一般情况下载布局文件中这么书写: //在布局文件里的代码<ProgressBarandroid ...

最新文章

  1. 《编写高质量代码:改善Java程序的151个建议》笔记
  2. java面试难吗_面试两个月,整理了今年的最新java面试题,你看行吗?
  3. php表白情话,向一个人表白 抖音最火99句情话告白
  4. linux下安装jdk,非常简单的操作
  5. java jdbc事务管理_hibernate事务管理 (jdbc jta)
  6. C++ STL容器之map 简单使用
  7. linux c 获取时间戳 打印时间戳
  8. mariadb10.2 mysql5.7_说说在MySQL5.7迁到MariaDB10.2时栽的一部分坑
  9. Cannot find class [***] for bean with name '***' defined in file[***]
  10. IOS APP提交流程
  11. postgresql 日期相减
  12. 计算机图像处理顶级教授,【科研新成果】我院两项成果被图像处理领域顶级期刊录用...
  13. 《scikit-learn机器学习实战》简介
  14. 为什么手机八核心还会卡?
  15. 汽车电子触摸屏产品EMC设计要领
  16. thinkphp update操作,某字段更新不成功
  17. 倍福PLC在NC轴报错代码18000原因分析
  18. 如何通过检测微芯片操作来对抗硬件木马
  19. web test IBM Page Detailer / IBM Rational Performance Tester / Web Page Performa
  20. JDBC Connection... will not be managed by Spring

热门文章

  1. web项目运行时无法重命名MySQL表问题排查
  2. php 计算今天周几,php如何计算当前日期是周几
  3. HDU 4622 Reincarnation 后缀自动机
  4. sql中between and 用法
  5. ubuntu hashcat 安装
  6. CSDN_MySQL入门技能树学习整理知识点
  7. 解决Shiro+SpringBoot异步任务长时间运行导致的UnknownSessionException错误问题
  8. 计算机科学与技术高校毕业生要求,计算机科学与技术专业 毕业要求(2016)
  9. Crashing Balloon
  10. 阿里云-学生成长计划领取资格考试 - 云计算及云服务器入门!超详细多题答案!白嫖阿里云服务器!