Android自定義垂直 SeekBar
阿新 • • 發佈:2021-02-14
技術標籤: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) {
}
});