自定义音量调节控件"/>
Android——自定义音量调节控件
今天我们要实现一个上图中音量调节的效果。主要有两种实现方式自定义RatingBar和自定义View。
自定义RatingBar
volume_rating.xml
<layer-list xmlns:android=""><item android:id="@android:id/background" android:drawable="@drawable/volume_off"/><item android:id="@android:id/secondaryProgress" android:drawable="@drawable/volume_on"/><item android:id="@android:id/progress" android:drawable="@drawable/volume_on"/>
</layer-list>
main.xml
<android.support.v7.widget.AppCompatRatingBarandroid:id="@+id/volume_ratingBar"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:numStars="6"android:paddingBottom="20dip"android:visibility="gone"android:paddingTop="20dip"android:max="10"android:progress="7"android:progressDrawable="@drawable/volume_rating"android:stepSize="1" />
这里注意一下,layer-list
中的drawable
必须是图片,不能用自己画的shape
,原因我也不清楚。
自定义View
attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="VolumeView"><attr name="volumeColor" format="color|reference" /><attr name="defaultVolumenColor" format="color|reference" /><attr name="max" format="integer"/><attr name="volume" format="integer"/></declare-styleable>
</resources>
VolumeView
public class VolumeView extends View {private Paint paint;// 控件宽度private int width = 430;// 控件高度private int height = 100;// 两个音量矩形最左侧之间的间隔private int rectMargin = 10;// 音量矩形高private int rectH = 30;// 音量矩形宽private int rectW = 15;// 未选中音量颜色private int unChoiceVolumeColor;// 选中音量颜色private int choiceVolumeColor;// 当前音量private int currentVolume;// 最大音量private int maxVolume;// 音量减-左坐标private int minusLeft;// 音量减-右坐标private int minusRight;// 音量加-左坐标private int plusLeft;// 音量加-右坐标private int plusRight;//音量图标private Bitmap volumeIcon;//音量关闭图标private Bitmap volumeCloseIcon;//减音量图标private Bitmap minusIcon;//加音量图标private Bitmap plusIcon;private OnVolumeChangedListener onVolumeChangedListener;public VolumeView(Context context) {this(context, null);}public VolumeView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public VolumeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.VolumeView);choiceVolumeColor = typedArray.getColor(R.styleable.VolumeView_volumeColor, Color.BLACK);unChoiceVolumeColor = typedArray.getColor(R.styleable.VolumeView_defaultVolumenColor, Color.WHITE);currentVolume = typedArray.getInteger(R.styleable.VolumeView_volume, 0);maxVolume = typedArray.getInteger(R.styleable.VolumeView_max, 0);typedArray.recycle();paint = new Paint();volumeIcon = BitmapFactory.decodeResource(getResources(), R.drawable.volume);volumeCloseIcon = BitmapFactory.decodeResource(getResources(), R.drawable.volume_close);minusIcon = BitmapFactory.decodeResource(getResources(), R.drawable.minus);plusIcon = BitmapFactory.decodeResource(getResources(), R.drawable.plus);}public void setOnVolumeChangedListener(OnVolumeChangedListener onVolumeChangedListener) {this.onVolumeChangedListener = onVolumeChangedListener;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if (onVolumeChangedListener != null) {onVolumeChangedListener.onVolumenChanged(currentVolume);}if (currentVolume == 0) {canvas.drawBitmap(volumeCloseIcon, 0, 0, paint);} else {canvas.drawBitmap(volumeIcon, 0, 0, paint);}int iconWidth = volumeIcon.getWidth();int iconHeight = volumeIcon.getHeight();int offsetTop = (iconHeight - minusIcon.getHeight()) / 2;int offsetLeft = iconWidth + rectMargin * 2;minusLeft = iconWidth;canvas.drawBitmap(minusIcon, offsetLeft, offsetTop, paint);int offsetVolumeLeft = offsetLeft + minusIcon.getWidth() + rectMargin * 2;minusRight = offsetVolumeLeft;int offsetVolumeTop = (iconHeight - rectH) / 2;paint.setColor(choiceVolumeColor);for (int i = 0; i < currentVolume; i++) {int left = offsetVolumeLeft + i * rectW + i * rectMargin;canvas.drawRect(left, offsetVolumeTop, left + rectW, offsetVolumeTop + rectH, paint);}paint.setColor(unChoiceVolumeColor);for (int i = currentVolume; i < maxVolume; i++) {int left = offsetVolumeLeft + i * rectW + i * rectMargin;canvas.drawRect(left, offsetVolumeTop, left + rectW, offsetVolumeTop + rectH, paint);}int offsetPlusTop = (iconHeight - plusIcon.getHeight()) / 2;int offsetPlusLeft = offsetVolumeLeft + maxVolume * rectW + maxVolume * rectMargin + rectMargin;plusLeft = offsetVolumeLeft + maxVolume * rectW + (maxVolume - 1) * rectMargin;plusRight = offsetPlusLeft + plusIcon.getWidth() + rectMargin;canvas.drawBitmap(plusIcon, offsetPlusLeft, offsetPlusTop, paint);}public void addVolume() {if (currentVolume >= maxVolume) {return;}currentVolume++;invalidate();}public void minusVolume() {if (currentVolume <= 0) {return;}currentVolume--;invalidate();}@Overridepublic boolean onTouchEvent(MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN) {float eventX = event.getX();if (eventX >= minusLeft && eventX <= minusRight) {//minusVolumeminusVolume();return true;} else if (eventX >= plusLeft && eventX <= plusRight) {//addVolumeaddVolume();return true;}}return super.onTouchEvent(event);}public interface OnVolumeChangedListener {void onVolumenChanged(int volume);}
}
MainActivity.java
volumeView.setOnVolumeChangedListener(volume -> {tvCurVolume.setText("当前音量:" + volume);
});
这里也注意下,Bitmap plusIcon = BitmapFactory.decodeResource(getResources(), R.drawable.plus);
同样不能用自己画的shape
,原因不详。
更多推荐
Android——自定义音量调节控件
发布评论