今天我们要实现一个上图中音量调节的效果。主要有两种实现方式自定义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,原因不详。

更多相关文章

  1. Android(安卓)加载大图片,不压缩图片
  2. Android(安卓)Drawable - Shape
  3. Android自定义控件:Android(安卓)L控件点击水波纹的实现(源码 + De
  4. android Region碰撞
  5. Android(安卓)ScrollView反弹效果的实现
  6. Android中ViewFlipper详解
  7. Android(安卓)MPChart—柱状图
  8. android开发大作业开发记录(关于制作圆角按钮)
  9. 【ArcGIS for Android】经纬度坐标、地图投影坐标、屏幕坐标互相

随机推荐

  1. 四、View的事件体系
  2. Android 中 shape 图形的使用
  3. android实现漫天雪花&下雨效果
  4. 申请Android(安卓)Maps API Key
  5. android记事本--geolo无聊版
  6. 阅读《Android 从入门到精通》(20)——图片
  7. android用户界面-布局管理Layout
  8. Android后台运行的定时器实现
  9. android手机开机动画相关代码解析
  10. Android 代码混淆及第三方jar包不被混淆