10

我想要如下图所示的垂直 seekBar (适用于 android 4.O+))。它在Google Play 音乐应用程序中。

在此处输入图像描述

我尝试过以下方式:但我无法设置高度和宽度

<SeekBar 
    android:id="@+id/seekBar1" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:rotation="270" 
    />  

我想像下面这样:

在此处输入图像描述

现在我已经使用了这个Stack Answer,但是管理多个垂直搜索栏太难了。

我正在寻找比这更好的方法。


编辑:

我使用了以下来自iDroid Explorer 的代码尝试显示垂直搜索栏:

private void setupEqualizerFxAndUI() {

        for (short i = 0; i < 5; i++) {

            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT);
            layoutParams.weight = 3;

            LinearLayout row = new LinearLayout(this);
            row.setOrientation(LinearLayout.VERTICAL);
            row.setLayoutParams(layoutParams);

            TextView minDbTextView = new TextView(this);
            minDbTextView.setLayoutParams(new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT));
            minDbTextView.setText(i + " dB");

            TextView maxDbTextView = new TextView(this);
            maxDbTextView.setLayoutParams(new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT));
            maxDbTextView.setText(i + " dB");

            LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
            layoutParams1.weight = 2;

            SeekBar bar = new SeekBar(this);
            bar.setLayoutParams(layoutParams1);
            bar.setMax(100);
            bar.setProgress(20);
            bar.setRotation(270);
            bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                public void onProgressChanged(SeekBar seekBar, int progress,
                        boolean fromUser) {

                }

                public void onStartTrackingTouch(SeekBar seekBar) {
                }

                public void onStopTrackingTouch(SeekBar seekBar) {
                }
            });

            row.addView(minDbTextView);
            row.addView(bar);
            row.addView(maxDbTextView);

            mLinearLayout.addView(row);

        }
    }

但如下所示:指标未显示。

在此处输入图像描述

如果我只使用一个 seekBar 那么它如下所示:

在此处输入图像描述

与使用相同:android:rotation="270"在布局文件中。

4

3 回答 3

10

iDroid Explorer 的代码很棒,帮助我完成了很多工作,但是它缺少一些部分。这是我的破解版本,它对我很有用,我希望它也对你有用。

public class VerticalSeekBar extends SeekBar {

    protected OnSeekBarChangeListener changeListener;
    protected int x, y, z, w;

    public VerticalSeekBar(Context context) {
        super(context);
    }

    public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public VerticalSeekBar(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected synchronized void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(h, w, oldh, oldw);

        this.x = w;
        this.y = h;
        this.z = oldw;
        this.w = oldh;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(heightMeasureSpec, widthMeasureSpec);
        setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
    }

    @Override
    protected void onDraw(Canvas c) {
        c.rotate(-90);
        c.translate(-getHeight(), 0);

        super.onDraw(c);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled()) {
            return false;
        }

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                setSelected(true);
                setPressed(true);
                if (changeListener != null) changeListener.onStartTrackingTouch(this);
                break;
            case MotionEvent.ACTION_UP:
                setSelected(false);
                setPressed(false);
                if (changeListener != null) changeListener.onStopTrackingTouch(this);
                break;
            case MotionEvent.ACTION_MOVE:
                int progress = getMax() - (int) (getMax() * event.getY() / getHeight());
                setProgress(progress);
                onSizeChanged(getWidth(), getHeight(), 0, 0);
                if (changeListener != null) changeListener.onProgressChanged(this, progress, true);
                break;

            case MotionEvent.ACTION_CANCEL:
                break;
        }
        return true;
    }

    @Override
    public synchronized void setOnSeekBarChangeListener(OnSeekBarChangeListener listener) {
        changeListener = listener;
    }

    @Override
    public synchronized void setProgress(int progress) {
        if (progress >= 0)
            super.setProgress(progress);

        else
            super.setProgress(0);
        onSizeChanged(x, y, z, w);
        if (changeListener != null) changeListener.onProgressChanged(this, progress, false);
    }
}
于 2013-11-11T08:16:59.677 回答
8

你检查过AudioFXDemo的 android 示例代码吗?如果没有,请检查它,看看它是否对您有帮助。

有与谷歌音乐应用程序相同的均衡器。

检查该演示示例中的以下代码:

    private void setupEqualizerFxAndUI() {
        // Create the Equalizer object (an AudioEffect subclass) and attach it to our media player,
        // with a default priority (0).
          try {
            System.out.println("setupEqualizerFxAndUI eEqualizer is: "+mEqualizer);
            System.out.println("setupEqualizerFxAndUI mIRemoteService: "+mIRemoteService);
            mEqualizer = new Equalizer(0,mIRemoteService.getAudioSessionId());
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (UnsupportedOperationException e) {
            e.printStackTrace();
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (RuntimeException e) {
            e.printStackTrace();
        } // Error in this line

        if(onOffBtn.isChecked()){  
            mEqualizer.setEnabled(true);
        }

        short bands = 5 ;
        //System.out.println("bands are: "+bands);

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);
        params.weight = 1;

        LinearLayout newOne = new LinearLayout(this);
        newOne.setLayoutParams(params);
        newOne.setOrientation(LinearLayout.HORIZONTAL);

        final short minEQLevel = mEqualizer.getBandLevelRange()[0];
        final short maxEQLevel = mEqualizer.getBandLevelRange()[1];

        //System.out.println("Minimum value::: "+minEQLevel);
        //System.out.println("Maximum value::: "+maxEQLevel);

        //VerticalSeekBar[] bar = new VerticalSeekBar[5];

        for (short i = 0; i < bands; i++) {
            final short band = i;

          /*  TextView freqTextView = new TextView(this);
            freqTextView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            freqTextView.setGravity(Gravity.CENTER_HORIZONTAL);
            freqTextView.setText((mEqualizer.getCenterFreq(band) / 1000) + " Hz");
            newOne.addView(freqTextView);*/

            LinearLayout row = new LinearLayout(this);

            row.setOrientation(LinearLayout.VERTICAL);

            TextView minDbTextView = new TextView(this);
            minDbTextView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT));
            minDbTextView.setText((minEQLevel / 100) + " dB");
            minDbTextView.setTextColor(0xff000000);

            TextView maxDbTextView = new TextView(this);
            maxDbTextView.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            maxDbTextView.setText((maxEQLevel / 100) + " dB");
            maxDbTextView.setTextColor(0xff000000);

            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 300);
            layoutParams.setMargins(0, 10, 0, 10);

//--------------------------

           // setClassicTone(maxEQLevel, minEQLevel);

            VerticalSeekBar bar =  new VerticalSeekBar(this);

            bar = new VerticalSeekBar(this);
            bar.setLayoutParams(layoutParams);
            bar.setMax(maxEQLevel - minEQLevel);
            bar.setProgress(mEqualizer.getBandLevel(band));
            //bar.setMax(3000);
            //bar.setProgress(mEqualizer.getBandLevel(band)+1500);
            bar.setPadding(0, 10, 0, 10);

            //bar.setProgressDrawable(R.drawable.scrubber_progress_horizontal_holo_light);
            bar.setProgressDrawable(getResources().getDrawable(R.drawable.scrubber_progress_horizontal_holo_light));
            bar.setThumb(getResources().getDrawable(R.drawable.scrubber_control_selector_holo));
            //System.out.println("Progress:::"+(mEqualizer.getBandLevel(band)));
            //bar[i].setProgress((maxEQLevel-minEQLevel)/2);
            mEqualizer.setBandLevel(band,(short) ((maxEQLevel-minEQLevel)));
            //System.out.println("Presets are: "+mEqualizer.getNumberOfPresets()+" And name is:  "+mEqualizer.getPresetName(i));

            //mEqualizer.setBandLevel(band, level)
            bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {
                    System.out.println("Seek bar change ");
                    presetsSpinner.setSelection(0);
                    mEqualizer.setBandLevel(band, (short) (progress + minEQLevel));

                }

                public void onStartTrackingTouch(SeekBar seekBar) {}
                public void onStopTrackingTouch(SeekBar seekBar) {}
            });

            row.addView(maxDbTextView);
            row.addView(bar);
            row.addView(minDbTextView);

            newOne.addView(row, params);
        }

        equalizerLayout.addView(newOne);
    }

VerticalSeekBar 是如下类:

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.SeekBar;

public class VerticalSeekBar extends SeekBar {

    public VerticalSeekBar(Context context) {
        super(context);
    }

    public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public VerticalSeekBar(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(h, w, oldh, oldw);
    }

    @Override
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(heightMeasureSpec, widthMeasureSpec);
        setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
    }

    protected void onDraw(Canvas c) {
        c.rotate(-90);
        c.translate(-getHeight(), 0);

        super.onDraw(c);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled()) {
            return false;
        }

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_UP:
                setProgress(getMax() - (int) (getMax() * event.getY() / getHeight()));
                onSizeChanged(getWidth(), getHeight(), 0, 0);

                break;

            case MotionEvent.ACTION_CANCEL:
                break;
        }
        return true;
    }
}

希望以上代码对您有所帮助。如果没有,请告诉我。

享受编码... :)

于 2013-08-28T09:28:26.480 回答
2

Apparently, equalizer is not part of Google Play Music, but rather a separate application called MusicFX (com.android.musicfx):

I/ActivityManager(536): START u0 {act=android.media.action.DISPLAY_AUDIO_EFFECT_CONTROL_PANEL cmp=com.android.musicfx/.Compatibility$Redirector (has extras)} from pid 4800
I/ActivityManager(536): START u0 {act=android.media.action.DISPLAY_AUDIO_EFFECT_CONTROL_PANEL flg=0x2000000 cmp=com.android.musicfx/.ActivityMusic (has extras)} from pid 4867
I/ActivityManager(536): Displayed com.android.musicfx/.ActivityMusic: +293ms (total +315ms)

The source code of MusicFX is available from Android repository.

Hope this helps.

于 2013-08-26T15:12:07.740 回答