【Android界面实现】自定义音量调节控件的实现

来源:互联网 发布:知不可乎骤得句式 编辑:程序博客网 时间:2024/05/17 02:24

本篇文章,将介绍如何实现自定义的音量调节控件。

话不多少,先看效果图



本篇文章将介绍两种实现的方式,上面的是通过继承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>
<span style="white-space:pre"></span>

在这里面设置了背景和选中时的图片显示。

通过设置这么多东西之后,我们就可以实现一开始显示出的上面那种效果,精度可以达到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();}@Overrideprotected 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);}@Overridepublic 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;}// 高度父布局要占用的位置大小@Overrideprotected 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() {@Overridepublic void onChange(int count) {tv.setText("当前音量:"+count);}});

我们可以看到,这样使用起来很方便,但是精度暂时只能达到1的程度,而且现在增减音量的图片还是摆设,暂时没什么功能。如果有高手能帮我改进一下,不胜感激!



上面是图片资源

下面是颜色值

<?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>



2 0
原创粉丝点击