自定义view之音量控制

最近一直在学习自定义view,我是hongyang的一个小粉,hongyang老大也是我辈之楷模啊,奈何,自己太菜,只能一步一步的去攀爬了,下面的这个是学习hongyang老大的文章之一,加上自己的理解,练习一下:先看效果图:

首先是自定义的属性:

<resources>
    <declare-styleable name="AudioControlView">
        <!--上方小块的颜色-->
        <attr name="upCircleColor" format="color"></attr>
        <!--下方小块的颜色-->
        <attr name="downCircleColor" format="color"></attr>
        <!--小块的间距-->
        <attr name="splitSize" format="integer"></attr>
        <!--小块的个数-->
        <attr name="blockCount" format="integer"></attr>
        <!--小块的宽度-->
        <attr name="circleWidth" format="dimension"></attr>
        <!--正中的图片-->
        <attr name="centerPic" format="reference"></attr>

    </declare-styleable>

</resources>

其次在布局文件中的属性值:

 <com.yinwei.definemyself.view.AudioControlView
        android:layout_width="300dp"
        android:layout_height="300dp"
        app:blockCount="40"
        app:centerPic="@drawable/test"
        app:circleWidth="13dp"
        app:downCircleColor="@android:color/holo_red_light"
        app:splitSize="7"
        app:upCircleColor="@android:color/darker_gray" />

具体的实现代码:

public class AudioControlView extends View {

    private int mUpCircleColor, mDownCircleColor, mBlockCount, mSplitSize, mCircleWidth;

    private Bitmap mCenterImage;

    private Paint paint;

    private RectF rectF;

    private int mWidth, mHeight, mRadius, mcenter;

    private int mCurrentCount = 7;

    public AudioControlView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public AudioControlView(Context context) {
        this(context, null);
    }

    public AudioControlView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AudioControlView, defStyleAttr, 0);

        mUpCircleColor = a.getColor(R.styleable.AudioControlView_upCircleColor, Color.WHITE);

        mDownCircleColor = a.getColor(R.styleable.AudioControlView_downCircleColor, Color.BLACK);

        mBlockCount = a.getInt(R.styleable.AudioControlView_blockCount, 10);

        mSplitSize = a.getInt(R.styleable.AudioControlView_splitSize, 3);

        mCircleWidth = a.getDimensionPixelSize(R.styleable.AudioControlView_circleWidth,
                (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 17, getResources().getDisplayMetrics()));

        mCenterImage = BitmapFactory.decodeResource(getResources(), a.getResourceId(R.styleable.AudioControlView_centerPic, 0));

        a.recycle();

        paint = new Paint();

        paint.setColor(mUpCircleColor);
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(7);

        rectF = new RectF();

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);

        int measureHeight = MeasureSpec.getSize(heightMeasureSpec);

        int measureWidth = MeasureSpec.getSize(widthMeasureSpec);

        if (heightMode == MeasureSpec.EXACTLY) {

            mHeight = measureHeight;//如果是确切的宽高,view就是测量的宽高,不考虑图片是否大于我们设定的宽高

        } else {

            mHeight = mCenterImage.getHeight() + getPaddingBottom() + getPaddingTop() + mCircleWidth;

        }

        if (widthMode == MeasureSpec.EXACTLY) {

            mWidth = measureWidth;

        } else {

            mWidth = mCenterImage.getWidth() + getPaddingRight() + getPaddingLeft() + mCircleWidth;

        }

        setMeasuredDimension(mWidth, mHeight);

    }

    @Override
    protected void onDraw(Canvas canvas) {

        mcenter = Math.min(mWidth, mHeight) / 2;

        mRadius = mcenter - mCircleWidth / 2;

        rectF.top = mHeight / 2 - mRadius;
        rectF.left = mWidth / 2 - mRadius;
        rectF.right = mWidth / 2 + mRadius;
        rectF.bottom = mHeight / 2 + mRadius;

        float blockSize = (360 * 1.0f - mBlockCount * mSplitSize) / mBlockCount;//每个弧线的长度

        //绘制小弧线块
        for (int i = 0; i < mBlockCount; i++) {

            canvas.drawArc(rectF, i * (blockSize + mSplitSize), blockSize, false, paint);//false或者true 是否连接圆心,一般绘制扇形的时候是true

        }

        paint.setColor(mDownCircleColor);

        // canvas.drawArc();四个参数分别为:1:在什么范围之内绘制的矩形 2:绘制的起始弧度 3:绘制的弧度块的度数 4:画笔
        for (int i = 0; i < mCurrentCount; i++) {

            canvas.drawArc(rectF, i * (blockSize + mSplitSize), blockSize, false, paint);

        }

        //画图片

        int innerRadius = mRadius - mCircleWidth / 2; //除去绘制的部分的内切圆的半径大小

        Rect rect = new Rect();

        int innerRectHeght = (int) Math.sqrt(2) * innerRadius * 1 / 2;//内切圆中矩形的边长

        //在内切圆的半径大小下计算需要绘制的图片的矩形
        rect.left = mWidth / 2 - innerRectHeght;
        rect.top = mHeight / 2 - innerRectHeght;
        rect.right = mWidth / 2 + innerRectHeght;
        rect.bottom = mHeight / 2 + innerRectHeght;

        //如果图片的高度和宽度小于所绘制矩形的高度,以中心点放置图片
        if (mCenterImage.getHeight() < innerRectHeght && mCenterImage.getWidth() < innerRectHeght) {

            int rectWidth = Math.max(mCenterImage.getHeight(), mCenterImage.getWidth());

            rect.top = mHeight / 2 - rectWidth / 2;
            rect.left = mWidth / 2 - rectWidth / 2;
            rect.right = mWidth / 2 + rectWidth / 2;
            rect.bottom = mHeight / 2 + rectWidth / 2;

        }

        canvas.drawBitmap(mCenterImage, null, rect, paint);

    }

}

嘿嘿,其他不说了,注释的比较详细,为了脱离贫困线而努力吧!~

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-08 02:52:38

自定义view之音量控制的相关文章

Android 自定义View (四) 视频音量调控

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24529807 今天没事逛eoe,看见有人求助要做一个下面的效果,我看下面一哥们说要用12张图片,这尼玛逆天的麻烦,仔细看了一下感觉自定义控件木有问题,就花点时间写了一个. 好了,进入正题,继续我们的自定义View四部曲. 1.先分许需要的属性,两个小块的颜色.一张中间的图片.间隙大小.一个多少个块块.分析完毕,开始写attr.xml [html] view plain copy

Android麦克风录音带音量大小动态显示的圆形自定义View

1.所谓无图无真相,先上效果图.我们要实现的就是中间那个录音的按钮,周边会显示一圈音量大小的波形 2.VolumCircleBar继承自View,我们进行了自定义,代码如下 package com.rdinfo.ccenglish.ui.ccprofile.view; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import andro

Android 自定义View

最近在看鸿洋大神的博客,在看到自定义部分View部分时,想到之前案子中经常会要用到"图片 + 文字"这类控件,如下图所示: 之前的做法是在布局文件中,将一个Image & TextView组件放在LinearLayout/RelativeLayout中.今天就尝试了通过自定义View的方式来实现"图片 + 文字"组件. 首先在/res/value/目录下新建attrs.xml文件,在该文件中为CustomTextView定义以下几个attr.分别为 1.文字

Android自定义View入门

View架构简介: 在Android中,控件主要以ViewGroup和View的形式存在.ViewGroup控件可以包含多个View控件,该复合控件负责其内部所有子控件的测量和绘制,并传递交互事件.如图, 在Android的移动开发中,每个Activity都包含了一个PhoneWindow对象,该对象将DecorView设置为应用窗口的根View.该视图上的所有监听事件都通过WindowManagerService来进行接收,并通过Activity来回调相应的onClickListener.De

Android自定义View(一、初体验自定义TextView)

转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51454685 本文出自:[openXu的博客] 目录: 继承View重写onDraw方法 自定义属性 onMeasure方法 MeasureSpec 分析为什么我们自定义的MyTextView设置了wrap_content却填充屏幕 重写onMeasure方法 自动换行 源码下载 对于一个Android攻城狮来说,自定义控件是一项必须掌握的重要技能点,然而对于大部分人而言,感觉自定义控件并

(转)[原] Android 自定义View 密码框 例子

遵从准则 暴露您view中所有影响可见外观的属性或者行为. 通过XML添加和设置样式 通过元素的属性来控制其外观和行为,支持和重要事件交流的事件监听器 详细步骤见:Android 自定义View步骤 样子 支持的样式 可以通过XML定义影响外边和行为的属性如下 边框圆角值,边框颜色,分割线颜色,边框宽度,密码长度,密码大小,密码颜色 <declare-styleable name="PasswordInputView"> <attr name="border

Android属性动画与自定义View——实现vivo x6更新系统的动画效果

晚上好,现在是凌晨两点半,然后我还在写代码.电脑里播放着<凌晨两点半>,晚上写代码,脑子更清醒,思路更清晰. 今天聊聊属性动画和自定义View搭配使用,前面都讲到自定义View和属性动画,但是一起用的还是不多,刚巧今晚手机提示我更新系统,我看到那个更新的动画还不错,仔细的分析了一下,于是我也决定写一个,不是一模一样的,但是效果和原理是一样的. 先看看图: 这是一张静态的图,这里有三个波浪线,当下载完之后,波浪线会往上活动,一直到消失. 所以难点也是在这个波浪线上.这个波浪线类似于一个水波纹,也

Android自定义View的一般步骤

1.设置当前View自定义属性 需要在res的values文件夹下新建个attrs文件,在attrs文件中设置相关的自定义属性 设置自定义属性的名称 <!-- format属性可以用来限制当前自定义的属性是什么类型, 中间可以用 | 来连接,表示可以支持多种类型 --> <attr name="user_defined_attribute" format="color" /> <!-- 可以指定枚举类型,用来自定义一些需要用户选择的属性

自定义view之onMeasure()

可以说重载onMeasure(),onLayout(),onDraw()三个函数构建了自定义View的外观形象.再加上onTouchEvent()等重载视图的行为,可以构建任何我们需要的可感知到的自定义View. 本节我们探索自定义View中onMeasure()起到了什么样的作用,题外要插的一句是,Activity框架,View框架中大量的on函数基本上都应用到了Template模式,掌握这一模式对于理解这些框架大有裨益. 我们知道,不管是自定义View还是系统提供的TextView这些,它们