上一篇文章实现了一个动态的圆弧控件,这篇文章在此基础上面继续实现一个简单的音量增减控件

一、首先看一下我们这次要实现的效果图:

二、在attrs.xml中添加自定义属性:


<?xml version="1.0" encoding="utf-8"?>
<resources><attr name="maxVoice" format="integer"/><attr name="currentVoice" format="integer"/><declare-styleable name="VoiceProgressBar"><attr name="maxVoice" /><attr name="currentVoice" /></declare-styleable>
</resources>

三、对应的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"android:orientation="horizontal"android:gravity="center_horizontal"android:padding="20dp"android:background="@mipmap/beautiful"tools:context="com.shi.androidstudio.brokenline.MainActivity"><TextView
        android:id="@+id/tv_subVoice"android:layout_width="50dp"android:layout_height="100dp"android:gravity="center"android:text="-"android:textSize="26sp" /><com.shi.androidstudio.brokenline.SimpleView_04
        android:id="@+id/simpleView_04"android:layout_width="150dp"android:layout_height="110dp"android:background="#DD3F3F3F"android:paddingLeft="30dp"android:paddingRight="30dp"android:paddingTop="10dp"android:paddingBottom="10dp"app:currentVoice="5"app:maxVoice="13" /><TextView
        android:id="@+id/tv_addVoice"android:layout_width="50dp"android:layout_height="100dp"android:gravity="center"android:text="+"android:textSize="20sp" />
</LinearLayout>

四、SimpleView_04自定义控件代码:


public class SimpleView_04 extends View {/*** 最大音量*/private int maxVoice;/*** 当前音量*/private int currentVoice;private Rect rectImage;public SimpleView_04(Context context) {this(context, null);}public SimpleView_04(Context context, AttributeSet attrs) {this(context, attrs, 0);}public SimpleView_04(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);/*** 获得我们所定义的自定义样式属性*/TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.VoiceProgressBar, defStyleAttr, 0);int length = a.getIndexCount();for (int i = 0; i < length; i++) {int attr = a.getIndex(i);switch (attr) {case R.styleable.VoiceProgressBar_maxVoice:maxVoice = a.getInt(attr, 15);break;case R.styleable.VoiceProgressBar_currentVoice:currentVoice = a.getInt(attr, 5);break;}}a.recycle();rectImage = new Rect();}//增加音量public void addVoice(){if(currentVoice < maxVoice) {currentVoice++;postInvalidate();}}//减少音量public void subVoice(){if(currentVoice > 0){currentVoice--;postInvalidate();}}//重写onDraw方法,绘制音量图案@Overrideprotected void onDraw(Canvas canvas) {Bitmap bitmapSilence = scaleBitmap(R.mipmap.silence);Bitmap bitmapVoice = scaleBitmap(R.mipmap.voice);Paint mPaint = new Paint();mPaint.setAntiAlias(true); // 消除锯齿mPaint.setStrokeWidth(5); // 设置圆环的宽度mPaint.setStrokeCap(Paint.Cap.ROUND); // 定义线段断电形状为圆头mPaint.setAntiAlias(true); // 消除锯齿mPaint.setStyle(Paint.Style.STROKE); // 设置空心RectF oval = new RectF();                       //RectF对象oval.left = getPaddingLeft();            //左边oval.top = getPaddingTop();             //上边oval.right = getMeasuredWidth()-getPaddingRight();           //右边oval.bottom = getMeasuredHeight()-getPaddingBottom();          //下边mPaint.setColor(Color.WHITE);for (int i=0; i<maxVoice; i++){canvas.drawArc(oval, 40-20.77f*i, -5f, false, mPaint);    //绘制圆弧}mPaint.setColor(Color.BLACK);for (int i=0; i<currentVoice; i++){canvas.drawArc(oval, 40-20.77f*i, -5f, false, mPaint);    //绘制圆弧}int mWidth = getMeasuredWidth();int mHeight = getMeasuredHeight();if(currentVoice == 0){rectImage.left = mWidth/2 - bitmapSilence.getWidth()/2;rectImage.right = mWidth/2 + bitmapSilence.getWidth()/2;rectImage.top = mHeight / 2 - bitmapSilence.getHeight() / 2;rectImage.bottom = mHeight/2 + bitmapSilence.getHeight()/2;canvas.drawBitmap(bitmapSilence,null,rectImage,mPaint);}else{rectImage.left = mWidth/2 - bitmapVoice.getWidth()/2;rectImage.right = mWidth/2 + bitmapVoice.getWidth()/2;rectImage.top = mHeight/2 - bitmapVoice.getHeight()/2;rectImage.bottom = mHeight/2 + bitmapVoice.getHeight()/2;canvas.drawBitmap(bitmapVoice,null,rectImage,mPaint);}}//对获取到的位图进行大小缩放private Bitmap scaleBitmap(int id){Bitmap mTImage = BitmapFactory.decodeResource(getResources(), id);// 获得图片的宽高int width = mTImage.getWidth();int height = mTImage.getHeight();// 设置想要的大小int newWidth = (getMeasuredWidth()-getPaddingLeft()-getPaddingRight())*2/3;int newHeight = (getMeasuredHeight()-getPaddingTop()-getPaddingBottom())*2/3;// 计算缩放比例float scaleWidth = ((float) newWidth) / width;float scaleHeight = ((float) newHeight) / height;// 取得想要缩放的matrix参数Matrix matrix = new Matrix();matrix.postScale(scaleWidth, scaleHeight);// 得到新的图片return Bitmap.createBitmap(mTImage, 0, 0, width, height, matrix, true);}}

到这里基本就实现了我们需要的自定义控件了。
附上demo下载

自定义控件实战四 音量增减控件相关推荐

  1. Android自定义控件实战——下拉刷新控件终结者:PullToRefreshLayout

    说到下拉刷新控件,网上版本有很多,很多软件也都有下拉刷新功能.有一个叫XListView的,我看别人用过,没看过是咋实现的,看这名字估计是继承自ListView修改的,不过效果看起来挺丑的,也没什么扩 ...

  2. ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl

    第四章 组合控件开发CompositeControl 大家好,今天我们来实现一个自定义的控件,之前我们已经知道了,要开发自定义的控件一般继承三个基 类:Control,WebControl,还有一个就 ...

  3. Plotly绘制金融时间序列图实战:配置滑动控件

    Plotly绘制金融时间序列图实战:配置滑动控件 # 可视化金融时间序列数据并设置时间粒度组件: import plotly as py import plotly.graph_objs as go ...

  4. 文字居中 qt_Qt编写自定义控件11-设备防区按钮控件

    前言 在很多项目应用中,需要根据数据动态生成对象显示在地图上,比如地图标注,同时还需要可拖动对象到指定位置显示,能有多种状态指示,安防领域一般用来表示防区或者设备,可以直接显示防区号,有多种状态颜色指 ...

  5. jquery网页刷新后控件失效_jquery动态增减控件如何才能不刷新页面

    已结贴√ 问题点数:20 回复次数:9 jquery动态增减控件如何才能不刷新页面 用jquery动态管理控件,可是每一次增减控件都会刷新页面,然后控件里面原来输入的值就都不在了,可以怎么来实现在动态 ...

  6. ESP32 开发笔记(四)LVGL控件学习 ColorPicker 颜色选择器控件

    先看效果,创建一个颜色选择器控件,设置事件回调动态显示当前选择的颜色值 开发板购买链接https://item.taobao.com/item.htm?spm=a2oq0.12575281.0.0.5 ...

  7. ESP32 开发笔记(四)LVGL控件学习 Canvas 画布控件

    先看效果,创建了两个画布,一个按钮,按钮是为了演示透明画布效果, 第一个画布先画一个不透明蓝色矩形再画透明矩形,透过画布可以看到下面的按钮 第二个面布画了一个圆角矩形中间填充过渡色,再画一个字符串,然 ...

  8. 鸡啄米之VS2010/MFC编程入门之二十四(常用控件:列表框控件ListBox)

    目录 一.目的: 1.点击列表框某个变量后,编辑框就显示出来这个变量名字 一.参考: 1.VS2010/MFC编程入门之二十四(常用控件:列表框控件ListBox) ①总结:good:亲测有效,适合多 ...

  9. JAVA知识点梳理第四部分——Swing控件

    JAVA整理知识点传送门: JAVA知识点拉理第一部分--常规知识 JAVA知识点梳理第二部分--接口.内部类.异常等等 JAVA知识点梳理第三部分--图形用户界面GUI部分 JAVA知识点梳理第四部 ...

最新文章

  1. KBMMW 的日志管理器
  2. Android draw bitmap 图片不显示的问题
  3. 网站服务器宕机,B站服务器宕机 股价短线走低冲上热搜 官方回复称因机房故障...
  4. 分布式系统唯一ID生成方案汇总【转】
  5. 【教程】怎么同时同时ping1000个IP地址?
  6. oracle虚拟用户是什么意思,lr脚本中oracle 2tier虚拟用户相关内容
  7. 【2018.3.17】模拟赛之一-ssl2574jzoj1368 无限序列【斐波那契数列】
  8. xpath之string(.)方法
  9. Python学习13 异常处理机制
  10. Python-import导入上级 本级 目录文件
  11. 信息系统开发平台OpenExpressApp:【OpenTest】 之 语法及其使用介绍
  12. 模拟串口收发数据Configure Virtual Serial Port Driver(VSPD)
  13. 计算机硬盘显示在右边,电脑中出现一个系统保留磁盘分区怎么解决
  14. div 背景色设置_DIV背景颜色设置
  15. [译] 海量视频时代下的内容发现之旅
  16. walking机器人仿真教程-应用-多点导航结合睡眠功能实现智能取药
  17. 书单|阿里、百度大咖联合强推的2018年必读好书清单
  18. 专业档案门类代码编码方案
  19. RK3399PRO-RKNN_DEMO模块开发最新资料下载
  20. 上半年净利由盈转亏,依赖游戏产品的汇量科技能否持续破局?

热门文章

  1. Camera2(api2) 打开过程(一)
  2. 人工智能行业市场分析
  3. ServerStatus-Toyo 服务器探针安装 解决Github无法访问问题
  4. 【计算机三级数据库技术】第4章 数据库应用系统功能设计与实现--附思维导图
  5. Gauss完全主元法(C#实现)——计算方法
  6. 安装Ubuntu14.04系统简易教程(使用rufus-3.1)
  7. 输出1900-2000年中是闰年的年份
  8. C语言qsort中的cmp函数定义
  9. 谁说app的视频抓取不了的?用Python爬取整个app视频
  10. linux 批量解压gz文件夹,linux 批量解压gz bz2文件