Android 自定义View 视频音量调控

转载至:http://blog.csdn.net/lmj623565791/article/details/24529807
自己重新实现了一遍,并在其中增加了详细的注释,以及优解决了音量可以无限加载的问题。

首先还是先看看效果图:

今天没事逛eoe,看见有人求助要做一个下面的效果,我看下面一哥们说要用12张图片,这尼玛逆天的麻烦,仔细看了一下感觉自定义控件木有问题,就花点时间写了一个。

好了,进入正题,继续我们的自定义View四部曲。

  • 1、自定义View的属性
  • 2、在View的构造方法中获得我们自定义的属性
  • [ 3、重写onMesure ]
  • 4、重写onDraw

1、先分许需要的属性,两个小块的颜色、一张中间的图片、间隙大小、一个多少个块块。分析完毕,开始写attr.xml

1<?xml version="1.0" encoding="utf-8"?> 2<resources> 3<!--CustomVolumControlBar--> 4 <attr name="vFirstColor" format="color" /> 5 <attr name="vSecondColor" format="color" /> 6 <attr name="vCircleWidth" format="dimension" /> 7 <attr name="vDotCount" format="integer" /> 8 <attr name="vSplitSize" format="integer" /> 9 <attr name="vBg" format="reference" /><!--注意格式--> 10 11 <declare-styleable name="CustomVolumControlBar"> 12 <attr name="vFirstColor" /> 13 <attr name="vSecondColor" /> 14 <attr name="vCircleWidth" /> 15 <attr name="vDotCount" /> 16 <attr name="vSplitSize" /> 17 <attr name="vBg" /> 18 19 </declare-styleable> 20</resources>

2、在构造中获取这些属性:

1/ 第一个圆的颜色 2 private int mFirstColor; 3 // 第二个圆的颜色 4 private int mSecondColor; 5 // 圆弧的宽度 6 private int mCircleWidth; 7 // 个数 8 private int mDotCount; 9 // 每个块块之间的间隙 10 private int mSplitSize; 11 // 中间的图片 12 private Bitmap mBg; 13 // 当前进度 14 private int mCurrentCount = 1; 15 // 画笔 16 private Paint mPaint; 17 private Rect mRect; 18 19public CustomVolumControlBar(Context context, AttributeSet attrs, int defStyleAttr) { 20 super(context, attrs, defStyleAttr); 21 TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomVolumControlBar, defStyleAttr, 0); 22 int indexCount = typedArray.getIndexCount(); 23 for (int i = 0; i < indexCount; i++) { 24 int arr = typedArray.getIndex(i); 25 switch (arr) { 26 case R.styleable.CustomVolumControlBar_vFirstColor: 27 mFirstColor = typedArray.getColor(arr, Color.BLACK); 28 break; 29 case R.styleable.CustomVolumControlBar_vSecondColor: 30 mSecondColor = typedArray.getColor(arr, Color.WHITE); 31 break; 32 case R.styleable.CustomVolumControlBar_vCircleWidth: 33 mCircleWidth = typedArray.getDimensionPixelSize(arr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 20, getResources().getDisplayMetrics())); 34 break; 35 case R.styleable.CustomVolumControlBar_vDotCount: 36 mDotCount = typedArray.getInt(arr, 20); 37 break; 38 case R.styleable.CustomVolumControlBar_vSplitSize: 39 mSplitSize = typedArray.getInt(arr, 20); 40 break; 41 case R.styleable.CustomVolumControlBar_vBg: 42 mBg = BitmapFactory.decodeResource(getResources(), typedArray.getResourceId(arr, 0)); 43 break; 44 } 45 } 46 typedArray.recycle(); 47 mPaint = new Paint(); 48 mRect = new Rect(); 49 }

3、重写onDraw

1@Override 2 protected void onDraw(Canvas canvas) { 3// super.onDraw(canvas); 4 mPaint.setAntiAlias(true); 5 mPaint.setStrokeWidth(mCircleWidth); 6 mPaint.setStrokeCap(Paint.Cap.ROUND);//定义线段断电形状为圆头 7 mPaint.setStyle(Paint.Style.STROKE);// 设置空心 8 int center = getWidth() / 2;// 获取圆心x坐标 9 int radius = center - mCircleWidth / 2;// 半径(***圆边在圆环的中间***) 10 /** * 椭圆 */ 11 drawOval(canvas, center, radius); 12 13 /** * 计算内切正方形的位置 */ 14 int relRadius = radius - mCircleWidth / 2;// 获得内圆的半径 15 16 /** * 内切正方形距离左边的距离(或顶部): * (内圆半径 - (更2 / 2) * 内圆半径) + 圆弧的宽度 */ 17 mRect.left = (int) (relRadius - Math.sqrt(2) / 2 * relRadius) + mCircleWidth; 18 mRect.top = (int) (relRadius - Math.sqrt(2) / 2 * relRadius) + mCircleWidth; 19 /** * 内切正方形距离左边的距离 + 正方形的边长(Math.sqrt(2) * relRadius) */ 20 mRect.right = (int) (mRect.left + Math.sqrt(2) * relRadius); 21 mRect.bottom = (int) (mRect.left + Math.sqrt(2) * relRadius); 22 23 24 /** * 如果图片比较小,那么根据图片的尺寸放置到正中心 */ 25 if (mBg.getWidth() < Math.sqrt(2) * relRadius) { 26 mRect.left = mCircleWidth + (relRadius - mBg.getWidth() / 2); 27 mRect.top = mCircleWidth + (relRadius - mBg.getWidth() / 2); 28 mRect.right = mCircleWidth + (relRadius + mBg.getWidth() / 2); 29 mRect.bottom = mCircleWidth + (relRadius + mBg.getWidth() / 2); 30 } 31 canvas.drawBitmap(mBg, null, mRect, mPaint); 32 33 } 34 35 /** * 根据参数画出每个小块 */ 36 private void drawOval(Canvas canvas, int center, int radius) { 37 /** * 根据需要的个数以及间隙计算每个块块所占的比例 * 360 ---> 每个块的大小 * ( 360 - 块个数 * 间距 ) / 块的个数 */ 38 float itemSize = (360 * 1.0f - mDotCount * mSplitSize) / mDotCount; 39 // 用于定义的圆的形状和大小的界限 40 RectF oval = new RectF(center - radius, center - radius, center + radius, center + radius); 41 42 /** * 画圆环的第一种颜色 */ 43 mPaint.setColor(mFirstColor);// 设置圆环的颜色 44 for (int i = 0; i < mDotCount; i++) { 45 // 根据进度画圆弧 46 canvas.drawArc(oval, (i * (itemSize + mSplitSize)), itemSize, false, mPaint); 47 } 48 49 /** * 画圆环的第二种颜色 mCurrentCount */ 50 mPaint.setColor(mSecondColor);// 设置圆环的颜色 51 for (int i = 0; i < mCurrentCount; i++) { 52 // canvas.drawArc(rectF, -90, mProgress, false, mPaint);// 根据进度画圆弧 53 // 根据进度画圆弧 54 canvas.drawArc(oval, i * (itemSize + mSplitSize), itemSize, false, mPaint); 55 } 56 }

这里需要注意下:
画块:首先根据块数量和间隙计算,每个块所占的比例。
画图:当图比较大时,直接使用该环内切正方形大小进行约束,当图片比较小时,在正中心的位置绘制。有些数学运算过程,楼主在草稿上画了一会,不复杂,大家自己画画,我就不贴草稿了。

4、添加触摸监听:

1 /** * 添加触摸监听 * 当前数量+1 */ 2 public void up() { 3 if (mCurrentCount < mDotCount) { 4 mCurrentCount++; 5 } 6 postInvalidate(); 7 } 8 9 public void down() { 10 if (mCurrentCount > 0) { 11 mCurrentCount--; 12 } 13 postInvalidate(); 14 } 15 16 private int xDown, xUp; 17 18 @Override 19 public boolean onTouchEvent(MotionEvent event) { 20// return super.onTouchEvent(event); 21 switch (event.getAction()) { 22 case MotionEvent.ACTION_DOWN: 23 xDown = (int) event.getY(); 24 break; 25 case MotionEvent.ACTION_UP: 26 xUp = (int) event.getY(); 27 if (xDown < xUp) { 28 down(); 29 } else { 30 up(); 31 } 32 break; 33 } 34 return true; 35 }

触摸监听也得很简单哈,基本能实现,大家也可以加个最小距离加速度什么的,都行。

最后,效果图:

效果图

源码点击此处查看

嘿嘿,留个言,顶一个哈~

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

P2P技术揭秘.P2P网络技术原理与典型系统开发

Modular.Java(2009.06)\.Craig.Walls.文字版.pdf:http://www.t00y.com/file/59501950(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fwww.t00y.com%2Ffile%2F59501950)\More.E

00:Java简单了解

浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。