10

I want Vertical seekBar like below image (for android 4.O+)). its in Google Play Music App.

enter image description here

i have tried below way: but i can't set hight & width

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

i want like below:

enter image description here

right now i have used this Stack Answer but its too hard to manage multiple vertical seekbar.

i am looking for better way than this.


EDIT:

i have used below code from iDroid Explorer's answer try to display vertical seek bar:

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);

        }
    }

but it looks like below: indicator is not showing.

enter image description here

if i use only one seekBar then its look like below:

enter image description here

it same like use : android:rotation="270" in layout file.

Community
  • 1
  • 1
Dhaval Parmar
  • 18,812
  • 8
  • 82
  • 177
  • create a custom class which extends the seekbar, and then create as many vertical seekbar you want – Sunil Mishra Aug 23 '13 at 05:30
  • @Dhawal Sodha: Can you please tell me which difficulty you are facing during implementing my code? or my code work for you? – Shreyash Mahajan Aug 29 '13 at 10:30
  • Using the native touch events from Android work pretty well to build custom views with a dragging feature, using the 'start position', 'delta' and 'end position' concepts. The Android API is very clear and stable when handling touch events, making the required logic a no brainer. – Léon Pelletier Dec 21 '15 at 02:40

3 Answers3

10

iDroid Explorer's code is great and helped me a lot getting the job done, however it is missing some parts. Here's my hacked version, it works great for me and I hope it does for you too.

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);
    }
}
Chrissi
  • 1,188
  • 10
  • 9
8

Have you check the android Sample code of AudioFXDemo? If not then please check it and see whether it is helpful to you or not.

There is Equalizer which is same as Google Music app have.

Check below code in that Demo Example:

    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);
    }

And the VerticalSeekBar is the class as below:

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;
    }
}

Hope above code help you. If not then let me know.

Enjoy Coding... :)

Shreyash Mahajan
  • 23,386
  • 35
  • 116
  • 188
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.

ozbek
  • 20,955
  • 5
  • 61
  • 84