1. 程式人生 > 其它 >Android自定義垂直 SeekBar

Android自定義垂直 SeekBar

技術標籤:Androidseekbarverticalondrawonmeasureandroid

概述

android 本身只有一個水平的 seekbar,開發需要使用垂直的seekbar就只能自己實現了,好在可以直接繼承水平seekbar,修改幾個過載事件即可
忘了放圖了,補上
預設水平SeekBar

自定義垂直SeekBar

下面的progress值顯示就是一TextView

例項

public class MyVerticalSeekBar extends androidx.appcompat.widget.AppCompatSeekBar {
    public MyVerticalSeekBar
(@NonNull Context context) { super(context); } public MyVerticalSeekBar(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public MyVerticalSeekBar(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr)
; } //onDraw事件中旋轉畫布,由水平變垂直 @Override protected void onDraw(Canvas canvas) { canvas.rotate(-90); canvas.translate(-getHeight(), 0); super.onDraw(canvas); } //measure事件中重新計算控制元件尺寸,對換寬高值 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{ super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = getMeasuredHeight(); int height = getMeasuredWidth(); setMeasuredDimension(width, height); } //切記加上尺寸變更時的事件,變更對換寬高值 @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(h, w, oldh, oldw); } //最後過載一下滑動事件,重新計算progress值 @SuppressLint("ClickableViewAccessibility") @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: //因為我這是向上滑動的,所以最大值乘Y軸的滑動比例得到上面的取值,實際值再用最大值去減即可 setProgress(getMax() - (int) (getMax() * event.getY() / getHeight())); onSizeChanged(getWidth(), getHeight(), 0, 0); break; } return true; } }

外觀

以上即可實現垂直的seekbar,但我在實際使用時,發現顯示不出來,拉大尺寸發現本身是有顯示出來的,但是位置什麼的都不對,感覺內部padding值很大。
嘗試自定義外觀測試下發現問題不在padding上,不過問題也解決了,那就加上自定義的外觀吧

滑動條樣式

在drawable目錄下新建一個ic_progress.xml樣式檔案,名字可隨意
裡面就是兩個專案,一個是未滑過時的背景色,一個是滑過後的顏色,另外加了點圓角,為了好看

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:id="@android:id/background">
        <shape>
            <solid android:color="@color/white2" />
            <corners android:radius="5dp" />
        </shape>
    </item>

    <item android:id="@android:id/secondaryProgress">
        <clip>
            <shape>
                <solid android:color="@color/teal_200" />
                <corners android:radius="5dp" />
            </shape>
        </clip>
    </item>
</layer-list>
設定屬性
android:progressDrawable="@drawable/ic_progress"

圖示樣式

這個隨便找個喜歡的圖片就行,為了水平垂直變更後不會太醜,儘量找個圓環類似的圖片

android:thumb="@drawable/ic_thumb"

最後

最後就完成啦,直接像其他控制元件一樣進行引用就行啦
記得設定寬高值的時候還是要按水平的seekbar進行設定

<com.zqunyan.zgfloatmenu.utils.MyVerticalSeekBar
    android:id="@+id/seek_gesture_duration"
    android:layout_width="150dp"
    android:layout_height="24dp"
    android:thumb="@drawable/ic_thumb"
    android:progressDrawable="@drawable/ic_progress"
    app:layout_constraintStart_toStartOf="@+id/iv_gesture_stop"
    app:layout_constraintEnd_toEndOf="@+id/iv_gesture_stop"
    app:layout_constraintTop_toBottomOf="@+id/iv_gesture_stop" />

程式碼中使用

floatView.seekGestureDuration.setMax(9000);
floatView.seekGestureDuration.setProgress(3600);
floatView.seekGestureDuration.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
    @Override
    public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
        floatView.tvGestureDuration.setText(String.valueOf(i));
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

    }
});