VoiceLoadView 声音精度显示

VoiceLoadView,音量进度显示的view

下面这张图大家都看到过吧

20140426135735437.jpeg

在很多视频播放的地方常常看到这样的音量进度显示的图片.有人选择用很多张图片来叠加显示效果,虽然可以完成功能,似乎选择用图片还是比较麻烦的吧,有可能还会影响速度

这里就写了这样一个自定义view,来显示音量的控制.

动态图如下:

1493703912476.mp4_1493738906.gif

github链接
VoiceLoadView 源码
很多的自定义View

使用起来也比较简单

属性 含义
bg 中间的图片
firstColor 最外层的颜色
secondColor 进度显示的颜色
dotCount 进度显示的个数
splitSize 每一个进度点之间的间距
circleRadio 圆圈的半径
imageDevide 中间图片与外层进度点的距离,默认内切
circleWidth 进度点的宽度

在XML中可以这么写

<com.yk.myselfview.views.VoiceLoadView
    android:layout_width="150dp"
    android:layout_height="150dp"
    yk:bg="@mipmap/icon"
    yk:circleWidth="6"
    yk:firstColor="#00fc26"
    yk:secondColor="#f24c4f"
    yk:dotCount="10"
    yk:splitSize="20"
    yk:circleRadio="40"
    yk:imageDevide="0"
    />

在activity中

    mVoiceLoadView = (VoiceLoadView) findViewById(R.id.voiceloadview);
    mVoiceLoadView.setCurrentCount(0);//当前进度,设置值必须小于等于dotCount个数.这就是进度的设置方法

这样就可以完成音量的显示了.

实现代码

/**
 * Created by yukun on 17-5-2.
 */
public class VoiceLoadView extends View {
    private Paint mPaint=new Paint();
    private int mWidth;
    private int mHeight;
    private int mRadio;
    private int arcCount;
    private int mCurrentCount=6;
    private int mSplitSize;
    private int mCircleWidth;
    private Rect mRect=new Rect();
    private Bitmap mImage;
    private double mRectImage;
    private int mFirstColor;
    private int mSecondColor;
    private int mImageDevide;

    public void setCurrentCount(int currentCount) {
        mCurrentCount = currentCount;
        invalidate();
    }

    public VoiceLoadView(Context context) {
        super(context);
        init(context,null,0);

    }

    public VoiceLoadView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context,attrs,0);

    }

    public VoiceLoadView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context,attrs,defStyleAttr);
    }

    private void init(Context context, AttributeSet attrs, int defStyleAttr) {

        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.VoiceLoadView, defStyleAttr, 0);
        int n = a.getIndexCount();

        for (int i = 0; i < n; i++) {
            int attr = a.getIndex(i);
            switch (attr) {
                case R.styleable.VoiceLoadView_firstColor:
                    mFirstColor = a.getColor(attr, Color.GREEN);
                    break;
                case R.styleable.VoiceLoadView_secondColor:
                    mSecondColor = a.getColor(attr, Color.CYAN);
                    break;
                case R.styleable.VoiceLoadView_bg:
                    mImage = BitmapFactory.decodeResource(getResources(), a.getResourceId(attr, 0));
                    break;
                case R.styleable.VoiceLoadView_circleWidth:
                    mCircleWidth = dip2px(context,a.getInt(attr,20));
                    break;
                case R.styleable.VoiceLoadView_dotCount:
                    arcCount = a.getInt(attr, 10);// 默认20
                    break;
                case R.styleable.VoiceLoadView_splitSize:
                    mSplitSize = a.getInt(attr,20);
//                    mSplitSize = dip2px(context,a.getInt(attr,20));
                    break;
                case R.styleable.VoiceLoadView_circleRadio:
                    mRadio = dip2px(context,a.getInt(attr,20));
                    break;
                case R.styleable.VoiceLoadView_imageDevide:
                    mImageDevide = dip2px(context,a.getInt(attr,20));
                    break;
            }
        }
        a.recycle();
    }

    @Override
    protected void onSizeChanged(int w, iandroid 双手势nt h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        mPaint.setAntiAlias(true); // 消除锯齿
        mPaint.setStrokeWidth(mCircleWidth); // 设置圆环的宽度
        mPaint.setStrokeCap(Paint.Cap.ROUND); // 定义线段断电形状为圆头
        mPaint.setAntiAlias(true); // 消除锯齿
        mPaint.setStyle(Paint.Style.STROKE); // 设置空心

        /**
         * 根据需要画的个数以及间隙计算每个块块所占的比例*360
         */
        float itemSize = (360 * 1.0f - arcCount * mSplitSize) / arcCount;

        //中间显示矩形
        RectF oval = new RectF(mWidth/2 - mRadio, mHeight/2 - mRadio, mWidth/2 + mRadio, mHeight/2 + mRadio); // 用于定义的圆弧的形状和大小的界限

        mPaint.setColor(mFirstColor); // 设置圆环的颜色
        for (int i = 0; i < arcCount; i++) {
            canvas.drawArc(oval, i * (itemSize + mSplitSize), itemSize, false, mPaint); // 根据进度画圆弧
        }

        mPaint.setStrokeCap(Paint.Cap.ROUND); // 定义线段断电形状为圆头

        mPaint.setColor(mSecondColor); // 设置圆环的颜色
        for (int i = 0; i < mCurrentCount; i++) {
            canvas.drawArc(oval, i * (itemSize + mSplitSize), itemSize, false, mPaint); // 根据进度画圆弧
        }

        //bitmap
        int relRadius = mRadio - mCircleWidth / 2;// 获得内圆的半径
        /**
         * 内切正方形的距离左边 = mCircleWidth + relRadius - √2 / 2
         */
        mRectImage = Math.sqrt(2) * 1.0f / 2 * relRadius/*+mCircleWidth*/-mImageDevide; //这里获得内切矩形的半个边长

        mRect.left=(int)(mWidth/2-mRectImage);
        mRect.top = (int) (mHeight/2 - mRectImage);
        mRect.right = (int) (mRect.left + 2*mRectImage);
        mRect.bottom = (int) (mRect.top + 2*mRectImage);

        // 绘图
        canvas.drawBitmap(mImage, null, mRect, mPaint);
    }

    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}

以上就是实现自定义view的代码,主要是计算位置,和圆弧的显示

在ondraw里,主要代码都有注释.直接看注释就能明白

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        mPaint.setAntiAlias(true); // 消除锯齿
        mPaint.setStrokeWidth(mCircleWidth); // 设置圆环的宽度
        mPaint.setStrokeCap(Paint.Cap.ROUND); // 定义线段断电形状为圆头
        mPaint.setAntiAlias(true); // 消除锯齿
        mPaint.setStyle(Paint.Style.STROKE); // 设置空心

        /**
         * 根据需要画的个数以及间隙计算每个块块所占的比例*360
         */
        float itemSize = (360 * 1.0f - arcCount * mSplitSize) / arcCount;

        //中间显示矩形
        RectF oval = new RectF(mWidth/2 - mRadio, mHeight/2 - mRadio, mWidth/2 + mRadio, mHeight/2 + mRadio); // 用于定义的圆弧的形状和大小的界限

        mPaint.setColor(mFirstColor); // 设置圆环的颜色
        for (int i = 0; i < arcCount; i++) {
            canvas.drawArc(oval, i * (itemSize + mSplitSize), itemSize, false, mPaint); // 根据进度画圆弧
        }

        mPaint.setStrokeCap(Paint.Cap.ROUND); // 定义线段断电形状为圆头

        mPaint.setColor(mSecondColor); // 设置圆环的颜色
        for (int i = 0; i < mCurrentCount; i++) {
            canvas.drawArc(oval, i * (itemSize + mSplitSize), itemSize, false, mPaint); // 根据进度画圆弧
        }

        //bitmap
        int relRadius = mRadio - mCircleWidth / 2;// 获得内圆的半径
        /**
         * 内切正方形的距离左边 = mCircleWidth + relRadius - √2 / 2
         */
        mRectImage = Math.sqrt(2) * 1.0f / 2 * relRadius/*+mCircleWidth*/-mImageDevide; //这里获得内切矩形的半个边长

        mRect.left=(int)(mWidth/2-mRectImage);
        mRect.top = (int) (mHeight/2 - mRectImage);
        mRect.right = (int) (mRect.left + 2*mRectImage);
        mRect.bottom = (int) (mRect.top + 2*mRectImage);

        // 绘图
        canvas.drawBitmap(mImage, null, mRect, mPaint);
    }

下面放几个大图震楼

S70502-13454006.jpg

S70502-13453254.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容