Android——自定义音量调节控件
16lz
2021-01-25
今天我们要实现一个上图中音量调节的效果。主要有两种实现方式自定义RatingBar和自定义View。
自定义RatingBar
volume_rating.xml
main.xml
这里注意一下,layer-list
中的drawable
必须是图片,不能用自己画的shape
,原因我也不清楚。
自定义View
attrs.xml
<?xml version="1.0" encoding="utf-8"?>
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; } @Override protected 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(); } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { float eventX = event.getX(); if (eventX >= minusLeft && eventX <= minusRight) {//minusVolume minusVolume(); return true; } else if (eventX >= plusLeft && eventX <= plusRight) {//addVolume addVolume(); 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(安卓)加载大图片,不压缩图片
- Android(安卓)Drawable - Shape
- Android自定义控件:Android(安卓)L控件点击水波纹的实现(源码 + De
- android Region碰撞
- Android(安卓)ScrollView反弹效果的实现
- Android中ViewFlipper详解
- Android(安卓)MPChart—柱状图
- android开发大作业开发记录(关于制作圆角按钮)
- 【ArcGIS for Android】经纬度坐标、地图投影坐标、屏幕坐标互相