概述
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) {
}
});