• 基于鸿洋博客自定于View实现的android音量调节控件


    1.在values建立attrs.xml,写出你需要的属性:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <attr name="firstColor" format="color" />
        <attr name="secondColor" format="color" />
        <attr name="circleWidth" format="dimension" />
        <attr name="dotCount" format="integer" />
        <attr name="splitSize" format="integer" />
        <attr name="bg" format="reference" />
    
        <declare-styleable name="CustomVolumControlBar">
            <attr name="firstColor" />
            <attr name="secondColor" />
            <attr name="circleWidth" />
            <attr name="dotCount" />
            <attr name="splitSize" />
            <attr name="bg" />
        </declare-styleable>
    
    
    </resources>

    2.创建view类并实现所需要的业务,具体看代码,代码中写的很详细:

    package com.zzw.Custom.widget;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.graphics.RectF;
    import android.media.AudioManager;
    import android.os.Handler;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.util.TypedValue;
    import android.view.MotionEvent;
    import android.view.View;
    
    import com.zzw.Custom.R;
    
    /**
     * Created by zzw on 2016/6/1.
     * 描述:
     */
    public class CustomVolumControlBar extends View {
    
        /**
         * 第一圈的颜色
         */
        private int mFirstColor;
    
        /**
         * 第二圈的颜色
         */
        private int mSecondColor;
        /**
         * 圈的宽度
         */
        private int mCircleWidth;
        /**
         * 画笔
         */
        private Paint mPaint;
        /**
         * 当前进度
         */
        private int mCurrentCount = 3;
    
        /**
         * 中间的图片
         */
        private Bitmap mImage;
        /**
         * 每个块块间的间隙
         */
        private int mSplitSize;
        /**
         * 个数
         */
        private int mCount;
    
        /**
         * 中间图片界限
         */
        private Rect mRect;
    
        private AudioManager mAudioManager;
    
        private Handler mHandler = new Handler();
    
        public CustomVolumControlBar(Context context) {
            this(context, null);
        }
    
        public CustomVolumControlBar(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public CustomVolumControlBar(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.CustomVolumControlBar, defStyleAttr, 0);
            int n = a.getIndexCount();
            for (int i = 0; i < n; i++) {
                int attr = a.getIndex(i);
                switch (attr) {
                    case R.styleable.CustomVolumControlBar_firstColor:
                        this.mFirstColor = a.getColor(attr, Color.BLACK);
                        break;
    
                    case R.styleable.CustomVolumControlBar_secondColor:
                        this.mSecondColor = a.getColor(attr, Color.WHITE);
                        break;
    
                    case R.styleable.CustomVolumControlBar_circleWidth:
                        this.mCircleWidth = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
                                TypedValue.COMPLEX_UNIT_PX, 20, getResources().getDisplayMetrics()));
                        break;
    
                    case R.styleable.CustomVolumControlBar_dotCount:
                        this.mCount = a.getInt(attr, 20);// 默认20
                        break;
    
                    case R.styleable.CustomVolumControlBar_splitSize:
                        this.mSplitSize = a.getInt(attr, 20);
                        break;
    
                    case R.styleable.CustomVolumControlBar_bg:
                        this.mImage = BitmapFactory.decodeResource(getResources(), a.getResourceId(attr, 0));
                        break;
                }
            }
            a.recycle();
            mPaint = new Paint();
            mRect = new Rect();
            if (mAudioManager == null)
                mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
    
            /**
             * 获取到最大音量和当前音量
             */
            mCount = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
            mCurrentCount = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
    
            Log.e("=====", "mCount:" + mCount + "   mCurrentCount:" + mCurrentCount);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            mPaint.setAntiAlias(true);//消除锯齿
            mPaint.setStrokeWidth(mCircleWidth);//设置圆圈宽度
            mPaint.setStrokeCap(Paint.Cap.ROUND);//定义线段电形状圆头
            mPaint.setStyle(Paint.Style.FILL_AND_STROKE);//设置空心
            int centre = getWidth() / 2;//得到圆心
            int radius = centre - mCircleWidth / 2;//得到半径
    
            drawOval(canvas, centre, radius);
    
            /**
             * 计算内切正方形的位置
             */
            int relRadius = radius - mCircleWidth / 2;// 获得内圆的半径
            /**
             * 内切正方形的距离顶部 = mCircleWidth + relRadius - √2 / 2
             */
            mRect.left = (int) (relRadius - Math.sqrt(2) * 1.0f / 2 * relRadius) + mCircleWidth;
    
            /**
             * 内切正方形的距离左边 = mCircleWidth + relRadius - √2 / 2
             */
            mRect.top = (int) (relRadius - Math.sqrt(2) * 1.0f / 2 * relRadius) + mCircleWidth;
    
            mRect.bottom = (int) (mRect.left + Math.sqrt(2) * relRadius);
            mRect.right = (int) (mRect.left + Math.sqrt(2) * relRadius);
    
            /**
             * 如果图片比较小,那么根据图片的尺寸放置到正中心
             */
            if (mImage.getWidth() < Math.sqrt(2) * relRadius) {
                mRect.left = (int) (mRect.left + Math.sqrt(2) * relRadius * 1.0f / 2 - mImage.getWidth() * 1.0f / 2);
                mRect.top = (int) (mRect.top + Math.sqrt(2) * relRadius * 1.0f / 2 - mImage.getHeight() * 1.0f / 2);
                mRect.right = (int) (mRect.left + mImage.getWidth());
                mRect.bottom = (int) (mRect.top + mImage.getHeight());
            }
            // 绘图
            canvas.drawBitmap(mImage, null, mRect, mPaint);
        }
    
    
        /**
         * 画块块去
         */
        private void drawOval(Canvas canvas, int centre, int radius) {
    
            /**
             * 根据需要画的个数以及间隙计算每个块块所占的比例*360
             */
            float itemSize = (360 * 1.0f - mCount * mSplitSize) / mCount;
            /**
             * 用于定义的圆弧的形状和大小的界限
             */
            RectF oval = new RectF(centre - radius, centre - radius, centre + radius, centre + radius);
            mPaint.setColor(mFirstColor);// 设置圆环的颜色
            for (int i = 0; i < mCount; i++) {
                canvas.drawArc(oval, i * (itemSize + mSplitSize), itemSize, false, mPaint);// 根据进度画圆弧
            }
            mPaint.setColor(mSecondColor); // 设置圆环的颜色
            for (int i = 0; i < mCurrentCount; i++) {
                canvas.drawArc(oval, i * (itemSize + mSplitSize), itemSize, false, mPaint); // 根据进度画圆弧
            }
        }
    
    
        /**
         * 当前数量+1
         */
        public synchronized void up() {
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mCurrentCount++;
                    if (mCurrentCount > mCount)
                        mCurrentCount = mCount;
    
                    postInvalidate();
                    setVolume(mCurrentCount);
                }
            }, 100);
        }
    
        /**
         * 设置音量
         *
         * @param index
         */
        private void setVolume(int index) {
            mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 1);
        }
    
        /**
         * 当前数量-1
         */
        public synchronized void down() {
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mCurrentCount--;
                    if (mCurrentCount < 0)
                        mCurrentCount = 0;
                    postInvalidate();
                    setVolume(mCurrentCount);
                }
            }, 100);
        }
    
        private int lastY, nowY;
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
    
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    lastY = (int) event.getY();
                    break;
    
                case MotionEvent.ACTION_MOVE:
                    nowY = (int) event.getY();
                    int updateYCount = (nowY - lastY) / 30;
                    if (updateYCount > 0) {
                        for (int i = 0; i < updateYCount; i++) {
                            down();
                        }
                    } else if (updateYCount < 0) {
                        for (int i = updateYCount; i < 0; i++) {
                            up();
                        }
                    }
                    lastY = nowY;
                    break;
            }
            return true;
        }
    }

    3.在xml中引用:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.zzw.Custom.MainActivity">
    
        <com.zzw.Custom.widget.CustomVolumControlBar
            android:layout_width="300dp"
            android:layout_height="300dp"
            android:layout_centerInParent="true"
            app:bg="@mipmap/ic_horn"
            app:circleWidth="5dp"
            app:firstColor="@color/colorPrimary"
            app:secondColor="@color/colorAccent"
            app:splitSize="10" />
    </RelativeLayout>

    当然,在实际操作中OnTouch事件一般是放在activity或者Fragment里面的,只需在代码中复制出去即可

    最后十分感谢鸿洋大神,让我们学到了很多,该篇与鸿洋大神相关的的博客地址:http://blog.csdn.net/lmj623565791/article/details/24529807

    CustomVolumControlBar
  • 相关阅读:
    数据结构与算法题目集(中文)6-12 二叉搜索树的操作集 (30分)
    性能测试案例
    jmeter 常用监听器
    性能测试面试题
    jmeter 之 dubbo
    jmeter5 分布式测试,未成功
    jmeter之OPMS项目管理参数化与断言实战;
    jmeter时间戳处理相关
    jmeter控制器下遍历一组参数
    The Wall (medium)
  • 原文地址:https://www.cnblogs.com/zzw1994/p/5549989.html
Copyright © 2020-2023  润新知