自定义音量调节控件的实现
作者: 发布日期:2014-06-25 18:30:21
我来说两句(0)
0
Tag标签:音量 控件
本篇文章,将介绍如何实现自定义的音量调节控件。
话不多少,先看效果图
\
\
本篇文章将介绍两种实现的方式,上面的是通过继承RatingBar,然后设置样式获得的效果,下面的是通过继承自View,完全自定义的方式实现。
我们首先介绍第一种方式,也就是继承自RatingBar实现。
view sourceprint?
01.public class WmtRatingBar extends RatingBar {
02.
03.private OnRatingBarChanging mOnRatingBarChanging;
04.
05.public WmtRatingBar(Context context) {
06.super(context);
07.}
08.
09.public WmtRatingBar(Context context, AttributeSet attrs) {
10.super(context, attrs);
11.}
12.
13.public WmtRatingBar(Context context, AttributeSet attrs, int defStyle) {
14.super(context, attrs, defStyle);
15.}
16.
17.
18.
19.@Override
20.public boolean onTouchEvent(MotionEvent event) {
21.switch (event.getAction()) {
22.case MotionEvent.ACTION_MOVE:
23.case MotionEvent.ACTION_DOWN:
24.case MotionEvent.ACTION_UP:
25.if (mOnRatingBarChanging != null)
26.mOnRatingBarChanging.onRatingChanging(this.getRating());
27.break;
28.}
29.return super.onTouchEvent(event);
30.
31.}
32.
33.public void setOnRatingBarChange(OnRatingBarChanging changing) {
34.mOnRatingBarChanging = changing;
35.}
36.
37.public interface OnRatingBarChanging {
38.void onRatingChanging(float f);
39.}
40.
41.}
我们可以看到,实现方式很简单,只不过是增加了一个接口,方便获取变化值。如果我们在布局文件中需要使用的话,需要这样
view sourceprint?
01.<com.wike.volume.WmtRatingBar
02.android:id="@+id/volume_ratingBar"
03.style="@style/wmtRatingBar"
04.android:layout_width="wrap_content"
05.android:layout_height="wrap_content"
06.android:layout_gravity="center_vertical"
07.android:numStars="15"
08.android:paddingBottom="20dip"
09.android:paddingTop="20dip" >
10.</com.wike.volume.WmtRatingBar>
这里很重要的一个就是设置style,我们看一下在style中是如何设置的
view sourceprint?
1.<resources>
2.<style name="wmtRatingBar" parent="@android:style/Widget.RatingBar">
3.<item name="android:progressDrawable">@drawable/wmt_ratingbar</item>
4.<item name="android:minHeight">16dip</item>
5.<item name="android:maxHeight">16dip</item>
6.</style>
7.</resources>
这里最重要的一个属性就是progressDrawable,这里定义了一个文件用于设置选中和不选中的图片显示,替代自带的五角星图形。
在wmt_ratingbar.xml中是这样设置的
view sourceprint?
1.<?xml version="1.0" encoding="utf-8"?>
2.<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
3.<item android:id="@+android:id/background" android:drawable="@drawable/ratingbar_off"></item>
4.<item android:id="@+android:id/secondaryProgress" android:drawable="@drawable/ratingbar_off"></item>
5.<item android:id="@+android:id/progress" android:drawable="@drawable/ratingbar_on"></item>
6.</layer-list>
在这里面设置了背景和选中时的图片显示。
通过设置这么多东西之后,我们就可以实现一开始显示出的上面那种效果,精度可以达到0.5
第一种实现方式比较简单,但是各种东西设置起来也是比较的繁琐,因此,我对第一种方案进行了修改,直接继承自View,然后完全自定义音频调节控件,下面看实现代码
view sourceprint?
001./**
002.* 自定义音量显示控件
003.*
004.* @author zhaokaiqiang
005.*
006.* @time 2014年6月25日 上午11:42:10
007.*/
008.public class VolumeView extends View {
009.
010.private static final String TAG = "VolumeView";
011.// 增加音量图片
012.private Bitmap addBitmap;
013.// 减少音量图片
014.private Bitmap reduceBitmap;
015.// 小喇叭图片
016.private Bitmap volume;
017.private Paint paint = new Paint();
018.// 控件高度
019.private int height = 100;
020.// 控件宽度
021.private int width = 430;
022.// 最大音量
023.private int MAX = 15;
024.// 两个音量矩形最左侧之间的间隔
025.private int rectMargen = 15;
026.// 音量矩形高
027.private int rectH = 20;
028.// 音量矩形宽
029.private int recW = 10;
030.// 当前选中的音量
031.private int current = 0;
032.// 最左侧音量矩形距离控件最左侧距离
033.private int leftMargen = 0;
034.
035.public VolumeView(Context context) {
036.super(context);
037.init();
038.}
039.
040.public VolumeView(Context context, AttributeSet attrs) {
041.super(context, attrs);
042.init();
043.}
044.
045.public VolumeView(Context context, AttributeSet attrs, int defStyleAttr) {
046.super(context, attrs, defStyleAttr);
047.init();
048.}
049.
050.
051.private void init() {
052.addBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.add);
053.volume = BitmapFactory.decodeResource(getResources(), R.drawable.volume);
054.reduceBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.reduce);
055.leftMargen = volume.getWidth() + reduceBitmap.getWidth();
056.}
057.
058.@Override
059.protected void onDraw(Canvas canvas) {
060.super.onDraw(canvas);
061.// 绘制背景颜色
062.paint.setColor(getResources().getColor(R.color.back_color));
063.canvas.drawRect(0, 0, width, height, paint);
064.
065.// 绘制没有被选中的白色音量矩形
066.paint.setColor(getResources().getColor(R.color.whrite));
067.for (int i = current; i < MAX; i++) {
068.canvas.drawRect(leftMargen + (i + 2) * rectMargen, (height - rectH) / 2, leftMargen + (i + 2) * rectMargen + recW, (height - rectH) / 2 + rectH,
069.paint);
070.}
071.
072.// 绘制被选中的橘黄色音量矩形
073.paint.setColor(getResources().getColor(R.color.orange));
074.for (int i = 0; i < current; i++) {
075.canvas.drawRect(leftMargen + (i + 2) * rectMargen, (height - rectH) / 2, leftMargen + (i + 2) * rectMargen + recW, (height - rectH) / 2 + rectH,
076.paint);
077.}
078.// 绘制音量图片
079.canvas.drawBitmap(volume, volume.getWidth() / 2, (height - volume.getHeight()) / 2, paint);
080.// 绘制音量减少图片
081.canvas.drawBitmap(reduceBitmap, reduceBitmap.getWidth() / 2 + volume.getWidth(), (height - reduceBitmap.getHeight()) / 2, paint);
082.// 绘制音量增加图片
083.canvas.drawBitmap(addBitmap, leftMargen + (MAX + 2) * rectMargen, (height - addBitmap.getHeight()) / 2, paint);
084.
085.}
086.
087.@Override
088.public boolean onTouchEvent(MotionEvent event) {
089.switch (event.getAction()) {
090.case MotionEvent.ACTION_DOWN:
091.case MotionEvent.ACTION_UP:
092.case MotionEvent.ACTION_MOVE:
093.// 当触摸位置在音量矩形之内时,获取当前选中的音量矩形数量
094.if ((event.getX() > leftMargen + rectMargen && event.getX() < leftMargen + (MAX + 1) * rectMargen + recW)
095.&& (event.getY() > (height - rectH) / 2 && event.getY() < (height - rectH) / 2 + rectH)) {
096.current = (int) ((event.getX() - (leftMargen)) / (rectMargen)) - 1;
097.if (onChangeListener != null) {
098.onChangeListener.onChange(current);
099.}
100.Log.d(TAG, "current:" + current);
101.}
102.break;
103.}
104.// 通知界面刷新
105.invalidate();
106.// 拦截触摸事件
107.return true;
108.}
109.
110.// 高度父布局要占用的位置大小
111.@Override
112.protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
113.setMeasuredDimension(width, height);
114.}
115.
116.public interface OnChangeListener {
117.public void onChange(int count);
118.}
119.
120.private OnChangeListener onChangeListener;
121.
122.public void setOnChangeListener(OnChangeListener onChangeListener) {
123.this.onChangeListener = onChangeListener;
124.}
125.
126.}
通过这个自定义的类,我们就实现了这个音量调节控件,下面我们看一下使用方法。
在布局文件中
view sourceprint?
1.<com.wike.volume.VolumeView
2.android:id="@+id/volumeView"
3.android:layout_width="wrap_content"
4.android:layout_height="wrap_content" />
在Activity中调用
view sourceprint?
1.view.setOnChangeListener(new OnChangeListener() {
2.
3.@Override
4.public void onChange(int count) {
5.tv.setText("当前音量:"+count);
6.}
7.});
我们可以看到,这样使用起来很方便,但是精度暂时只能达到1的程度,而且现在增减音量的图片还是摆设,暂时没什么功能。如果有高手能帮我改进一下,不胜感激!
\\\\\
上面是图片资源
下面是颜色值
view sourceprint?
1.<?xml version="1.0" encoding="utf-8"?>
2.<resources>
3.
4.<color name="back_color">#b0000000</color>
5.<color name="whrite">#ffffff</color>
6.<color name="orange">#FFB90F</color>
7.</resources>