本篇文章,将介绍如何实现自定义的音量调节控件。
话不多少,先看效果图
本篇文章将介绍两种实现的方式,上面的是通过继承RatingBar,然后设置样式获得的效果,下面的是通过继承自View,完全自定义的方式实现。
我们首先介绍第一种方式,也就是继承自RatingBar实现。
public class WmtRatingBar extends RatingBar { private OnRatingBarChanging mOnRatingBarChanging; public WmtRatingBar(Context context) { super(context); } public WmtRatingBar(Context context, AttributeSet attrs) { super(context, attrs); } public WmtRatingBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_UP: if (mOnRatingBarChanging != null) mOnRatingBarChanging.onRatingChanging(this.getRating()); break; } return super.onTouchEvent(event); } public void setOnRatingBarChange(OnRatingBarChanging changing) { mOnRatingBarChanging = changing; } public interface OnRatingBarChanging { void onRatingChanging(float f); } }我们可以看到,实现方式很简单,只不过是增加了一个接口,方便获取变化值。如果我们在布局文件中需要使用的话,需要这样
<com.wike.volume.WmtRatingBar android:id="@+id/volume_ratingBar" style="@style/wmtRatingBar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:numStars="15" android:paddingBottom="20dip" android:paddingTop="20dip" > </com.wike.volume.WmtRatingBar>这里很重要的一个就是设置style,我们看一下在style中是如何设置的
<resources> <style name="wmtRatingBar" parent="@android:style/Widget.RatingBar"> <item name="android:progressDrawable">@drawable/wmt_ratingbar</item> <item name="android:minHeight">16dip</item> <item name="android:maxHeight">16dip</item> </style> </resources>这里最重要的一个属性就是progressDrawable,这里定义了一个文件用于设置选中和不选中的图片显示,替代自带的五角星图形。
在wmt_ratingbar.xml中是这样设置的
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+android:id/background" android:drawable="@drawable/ratingbar_off"></item> <item android:id="@+android:id/secondaryProgress" android:drawable="@drawable/ratingbar_off"></item> <item android:id="@+android:id/progress" android:drawable="@drawable/ratingbar_on"></item> </layer-list>在这里面设置了背景和选中时的图片显示。
通过设置这么多东西之后,我们就可以实现一开始显示出的上面那种效果,精度可以达到0.5
第一种实现方式比较简单,但是各种东西设置起来也是比较的繁琐,因此,我对第一种方案进行了修改,直接继承自View,然后完全自定义音频调节控件,下面看实现代码
/** * 自定义音量显示控件 * * @author zhaokaiqiang * * @time 2014年6月25日 上午11:42:10 */ public class VolumeView extends View { private static final String TAG = "VolumeView"; // 增加音量图片 private Bitmap addBitmap; // 减少音量图片 private Bitmap reduceBitmap; // 小喇叭图片 private Bitmap volume; private Paint paint = new Paint(); // 控件高度 private int height = 100; // 控件宽度 private int width = 430; // 最大音量 private int MAX = 15; // 两个音量矩形最左侧之间的间隔 private int rectMargen = 15; // 音量矩形高 private int rectH = 20; // 音量矩形宽 private int recW = 10; // 当前选中的音量 private int current = 0; // 最左侧音量矩形距离控件最左侧距离 private int leftMargen = 0; public VolumeView(Context context) { super(context); init(); } public VolumeView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public VolumeView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { addBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.add); volume = BitmapFactory.decodeResource(getResources(), R.drawable.volume); reduceBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.reduce); leftMargen = volume.getWidth() + reduceBitmap.getWidth(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 绘制背景颜色 paint.setColor(getResources().getColor(R.color.back_color)); canvas.drawRect(0, 0, width, height, paint); // 绘制没有被选中的白色音量矩形 paint.setColor(getResources().getColor(R.color.whrite)); for (int i = current; i < MAX; i++) { canvas.drawRect(leftMargen + (i + 2) * rectMargen, (height - rectH) / 2, leftMargen + (i + 2) * rectMargen + recW, (height - rectH) / 2 + rectH, paint); } // 绘制被选中的橘黄色音量矩形 paint.setColor(getResources().getColor(R.color.orange)); for (int i = 0; i < current; i++) { canvas.drawRect(leftMargen + (i + 2) * rectMargen, (height - rectH) / 2, leftMargen + (i + 2) * rectMargen + recW, (height - rectH) / 2 + rectH, paint); } // 绘制音量图片 canvas.drawBitmap(volume, volume.getWidth() / 2, (height - volume.getHeight()) / 2, paint); // 绘制音量减少图片 canvas.drawBitmap(reduceBitmap, reduceBitmap.getWidth() / 2 + volume.getWidth(), (height - reduceBitmap.getHeight()) / 2, paint); // 绘制音量增加图片 canvas.drawBitmap(addBitmap, leftMargen + (MAX + 2) * rectMargen, (height - addBitmap.getHeight()) / 2, paint); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_UP: case MotionEvent.ACTION_MOVE: // 当触摸位置在音量矩形之内时,获取当前选中的音量矩形数量 if ((event.getX() > leftMargen + rectMargen && event.getX() < leftMargen + (MAX + 1) * rectMargen + recW) && (event.getY() > (height - rectH) / 2 && event.getY() < (height - rectH) / 2 + rectH)) { current = (int) ((event.getX() - (leftMargen)) / (rectMargen)) - 1; if (onChangeListener != null) { onChangeListener.onChange(current); } Log.d(TAG, "current:" + current); } break; } // 通知界面刷新 invalidate(); // 拦截触摸事件 return true; } // 高度父布局要占用的位置大小 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(width, height); } public interface OnChangeListener { public void onChange(int count); } private OnChangeListener onChangeListener; public void setOnChangeListener(OnChangeListener onChangeListener) { this.onChangeListener = onChangeListener; } }通过这个自定义的类,我们就实现了这个音量调节控件,下面我们看一下使用方法。
在布局文件中
<com.wike.volume.VolumeView android:id="@+id/volumeView" android:layout_width="wrap_content" android:layout_height="wrap_content" />在Activity中调用
view.setOnChangeListener(new OnChangeListener() { @Override public void onChange(int count) { tv.setText("当前音量:"+count); } });
上面是图片资源
下面是颜色值
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="back_color">#b0000000</color> <color name="whrite">#ffffff</color> <color name="orange">#FFB90F</color> </resources>
原文地址:http://blog.csdn.net/zhaokaiqiang1992/article/details/34441229