本篇文章,将介绍如何实现自定义的音量调节控件。
话不多少,先看效果图
本篇文章将介绍两种实现的方式,上面的是通过继承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);
}
}
我们可以看到,实现方式很简单,只不过是增加了一个接口,方便获取变化值。如果我们在布局文件中需要使用的话,需要这样
这里很重要的一个就是设置style,我们看一下在style中是如何设置的
这里最重要的一个属性就是progressDrawable,这里定义了一个文件用于设置选中和不选中的图片显示,替代自带的五角星图形。
在wmt_ratingbar.xml中是这样设置的
在这里面设置了背景和选中时的图片显示。
通过设置这么多东西之后,我们就可以实现一开始显示出的上面那种效果,精度可以达到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;
}
}
通过这个自定义的类,我们就实现了这个音量调节控件,下面我们看一下使用方法。
在布局文件中
在Activity中调用
view.setOnChangeListener(new OnChangeListener() {
@Override
public void onChange(int count) {
tv.setText("当前音量:"+count);
}
});
上面是图片资源
下面是颜色值
#b0000000
#ffffff
#FFB90F