Android 自定义均衡器View

零.前言

​   在一些音乐或者音效应用中经常可以看到均衡器调节,之前在工作也做过类似效果,特此记录一下。效果如下图:
在这里插入图片描述

一.思路

  1. 自定义竖向SeekBar
  2. 自定义13段竖向SeekBar的Recycleview
  3. Recycleview 添加SeekBar上下滑动的悬浮文本提示或者顶部指示器
    在这里插入图片描述

二.关键代码

​   1. 自定义一个矩形进度条(EqSquareProgress.java)

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int count = (max - min) / step + 1;
        for (int i = 0; i < count; i++) {
            // 从下往上绘制
            float startX = getPaddingLeft();
            float lineHeight = ResUtils.getDimension(R.dimen.eq_progress_line);
            float startY = getHeight() - ResUtils.getDimension(R.dimen.eq_progress_line_all) * i - lineHeight;
            float stopX = getWidth() - getPaddingRight();
            float stopY = startY;
            if (min + i * step <= progress) {
                paint.setColor(colorAdjusted);
            } else {
                paint.setColor(colorDefault);
            }
            if (adjusting) {
                if (min + i * step <= progress) {
                    paint.setColor(colorAdjusting);
                }
            }
            canvas.drawLine(startX, startY, stopX, stopY, paint);
            // 绘制游标
            if (adjusting && min + i * step == progress) {
                paint.setColor(colorAdjusting);
                float cursorMargin = ResUtils.getDimension(R.dimen.eq_progress_cursor_margin);
                float cursorHeight = ResUtils.getDimension(R.dimen.eq_progress_cursor_size);
                float cursorWidth = (float) (cursorHeight * 1.0F / 2 * Math.tan(Math.PI / 3));
                cursorPath.reset();
                cursorPath.moveTo(startX - cursorMargin, startY);
                cursorPath.lineTo(startX - cursorMargin - cursorWidth, startY - cursorHeight * 1.0F / 2);
                cursorPath.lineTo(startX - cursorMargin - cursorWidth, startY + cursorHeight * 1.0F / 2);
                cursorPath.lineTo(startX - cursorMargin, startY);
                cursorPath.close();
                canvas.drawPath(cursorPath, paint);
                cursorPath.reset();
                cursorPath.moveTo(stopX + cursorMargin, stopY);
                cursorPath.lineTo(stopX + cursorMargin + cursorWidth, stopY - cursorHeight * 1.0F / 2);
                cursorPath.lineTo(stopX + cursorMargin + cursorWidth, stopY + cursorHeight * 1.0F / 2);
                cursorPath.lineTo(stopX + cursorMargin, stopY);
                this.cursorPath.close();
                canvas.drawPath(cursorPath, paint);

            }
        }
    }

​ ​   2.自定义13段竖向SeekBar的Recycleview(EqSquareBars.java)

    // adapter
    private class ProgressAdapter extends RecyclerViewAdapter<DataBean> {

        ProgressAdapter(Context context, List<DataBean> datas) {
            super(context, datas);
        }

        @Override
        public int getItemLayoutId(int viewType) {
            return R.layout.view_eq_square_bars;
        }

        @Override
        public void onBindViewHolder(com.flyaudio.lib.adapter.Adapter.ViewHolder<DataBean> holder) {
            DataBean data = getData(holder.getItemPosition());
            EqSquareProgress progressBar = holder.getView(R.id.pb_progress);
            TextView tvTitle = holder.getView(R.id.tv_title);
            progressBar.setProgress(data.value);
            progressBar.setAdjusting(region == holder.getItemPosition());
            tvTitle.setText(data.title);
            setOnItemClickListener(EqSquareBars.this);

        }
    }
    
    // 构造函数中初始化数据,添加Adapter
     private void initData(Context context) {
        this.dataBeans = new ArrayList<>();
        this.adapter = new ProgressAdapter(context, dataBeans);

        paintText = new Paint();
        paintText.setAntiAlias(true);
        paintText.setTextSize(ResUtils.getDimension(R.dimen.eq_progress_font));
        paintLine = new Paint();
        paintLine.setColor(ResUtils.getColor(R.color.eq_progress_adjusting_color));
        paintLine.setStrokeWidth(ResUtils.getDimension(R.dimen.eq_progress_top_line));

        int[] eqFrequencies = EffectCommUtils.getFrequencies();
        String[] titles = getResources().getStringArray(R.array.eq_titles_13);
        for (int i = 0; i < titles.length; i++) {
            DataBean dataBean = new DataBean();
            dataBean.title = titles[i];
            dataBean.freq = eqFrequencies[i];
            this.dataBeans.add(dataBean);
        }
    }

    private void initView() {
        setAdapter(adapter);
        setHasFixedSize(true);
        setLayoutManager(new NoScrollLinearLayoutManager(getContext(), HORIZONTAL, false));
    }
    
   // 画顶部指示器 
   @Override
    public void onDraw(Canvas c) {
        super.onDraw(c);
        float y = getPaddingTop() + ResUtils.getDimension(R.dimen.eq_progress_font_height);
        float item = ResUtils.getDimension(R.dimen.eq_progress_item_width);
        float x;
        float startX1, startY1, stopX1, stopY1;
        float startX2, startY2, stopX2, stopY2;
        startY1 = stopY1 = startY2 = stopY2 = y - 0.30F * ResUtils.getDimension(R.dimen.eq_progress_font_height);
        if (region < REGION_BASS) {
            // 低音
            startX1 = getPaddingLeft() + item * 0.3F;
            stopX1 = item * 1.5F;
            startX2 = item * 2.4F;
            stopX2 = item * 3.7F;
        } else if (region < REGION_ALTO) {
            // 中音
            startX1 = item * 4.3F;
            stopX1 = item * 6F;
            startX2 = item * 7F;
            stopX2 = item * 8.7F;
        } else {
            // 高音
            startX1 = item * 9.2F;
            stopX1 = item * 10.5F;
            startX2 = item * 11.4F;
            stopX2 = item * 12.7F;
        }
        for (int i = 0; i < REGION_COUNT; i++) {
            x = item * (1.7F + 4.5F * i);
            String text = i == 0 ? ResUtils.getString(R.string.bass) : i == 1 ? ResUtils.getString(R.string.alto) :                                    ResUtils.getString(R.string.high);
            if (i == 0 && region < REGION_BASS) {
                paintText.setColor(ResUtils.getColor(R.color.eq_progress_adjusting_color));
            } else if (i == 1 && region >= REGION_BASS && region < REGION_ALTO) {
                paintText.setColor(ResUtils.getColor(R.color.eq_progress_adjusting_color));
            } else if (i == 2 && region >= REGION_ALTO) {
                paintText.setColor(ResUtils.getColor(R.color.eq_progress_adjusting_color));
            } else {
                paintText.setColor(ResUtils.getColor(R.color.text_color_normal8));
            }
            c.drawText(text, x, y, paintText);
        }
        c.drawLine(startX1, startY1, stopX1, stopY1, paintLine);
        c.drawLine(startX2, startY2, stopX2, stopY2, paintLine);
    }
    

三.github地址

​ ​    https://github.com/dongpingwang/DaXiaViewDemo/tree/master/views/EqualizerView

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值