自定义view之音量控制

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

<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);


    }


}

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

你可能感兴趣的:(练习,自定义view)