正负、中间向两侧滑动的seekbar
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了正负、中间向两侧滑动的seekbar相关的知识,希望对你有一定的参考价值。
参考技术A 由于项目需要,设计了一个可以正负滑动的seekbar,满足获取正负数值的需要/**
* 从中间可以向两边滑动 左负右正
* <p>
* Created by zhangjian on 2019/10/15 09:33
*/
public class CenterSeekBarView extends View
private static final int DEFAULT_TOUCH_TARGET_SIZE = 100;
private final Paint paint;
private float minUnit = 0.1f;
private int coefficient = 10;//增加的系数
private boolean canMove = false;
private float width = 400; // need <= getWidth()
/**
* progress start max
*/
private int minProgress = 0;
/**
* progress end max
*/
private int maxProgress = 100;
/**
* 进度条的颜色 底色 背景色
*/
@ColorInt
private int progressBackColor;
/**
* 进度条的颜色
*/
@ColorInt
private int progressColor;
/**
* current progress
*/
private int progress = 0;
/**
* seekBar Thumb normal radius
*/
private float mThumbRadius = 20;
private float progressPosition;
private boolean isTouchLegal = false;
private RectF mBackRectF, mProgressRectF;
private int mThumbDrawColor;
private OnSeekBarChangeListener mOnSeekBarChangeListener;
public CenterSeekBarView(Context context)
this(context, null);
public CenterSeekBarView(Context context, AttributeSet attrs)
this(context, attrs, 0);
public CenterSeekBarView(Context context, AttributeSet attrs, int defStyleAttr)
super(context, attrs, defStyleAttr);
paint = new Paint();
paint.setAntiAlias(true);
progressBackColor = Color.parseColor("#C2C2C2");
progressColor = Color.parseColor("#4388FF");
mThumbDrawColor = Color.parseColor("#4388FF");
mBackRectF = new RectF();
mProgressRectF = new RectF();
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getMeasuredWidth() - SizeUtils.dp2px(30);
public CenterSeekBarView setOnSeekBarChangeListener(OnSeekBarChangeListener l)
mOnSeekBarChangeListener = l;
return this;
public void delProgress()
setProgress(progress - (int) (minUnit * coefficient));
public void addProgress()
setProgress(progress + (int) (minUnit * coefficient));
public void reset()
setProgress(minProgress);
public void setProgress(int progress)
if (!canMove)
if (mOnSeekBarChangeListener != null)
mOnSeekBarChangeListener.onError();
return;
if (progress <= maxProgress && progress >= minProgress - maxProgress)
this.progress = progress;
if (mOnSeekBarChangeListener != null)
mOnSeekBarChangeListener.onProgress((float) progress / coefficient);
invalidate();
public void setCanMove(boolean canMove)
this.canMove = canMove;
@Override
protected void onDraw(Canvas canvas)
super.onDraw(canvas);
// Log.i("slack","onDraw... " + mThumbRadius);
int centerX = getWidth() / 2; // x 是center
int centerY = getHeight() / 2; // y 是 2/3 高度
float startX = centerX - width / 2;
// draw background line
paint.setColor(progressBackColor);
/**
* 进度条的 高度
*/
float progressHeight = 9;
paint.setStrokeWidth(progressHeight);
paint.setStyle(Paint.Style.FILL); // 实心
mBackRectF.left = startX;
mBackRectF.top = centerY - progressHeight;
mBackRectF.right = startX + width;
mBackRectF.bottom = centerY;
/**
* progress 字体 背景 radius
*/
canvas.drawRoundRect(mBackRectF, 10, 10, paint);
paint.setStyle(Paint.Style.FILL);
paint.setColor(progressColor);
paint.setStrokeWidth(progressHeight);
startX = centerX;
progressPosition = startX + (int) ((progress * (width / 2f) / (maxProgress - minProgress)));
mProgressRectF.top = centerY - progressHeight;
mProgressRectF.bottom = centerY;
if (progress > 0)
mProgressRectF.left = startX;
mProgressRectF.right = progressPosition;
else
mProgressRectF.left = progressPosition;
mProgressRectF.right = startX;
canvas.drawRoundRect(mProgressRectF, 10, 10, paint);
// draw point
paint.setColor(mThumbDrawColor);
canvas.drawCircle(progressPosition, centerY - progressHeight / 2, mThumbRadius, paint);
private long mLastTime;
@Override
public boolean onTouchEvent(MotionEvent event)
if (!isEnabled())
return false;
switch (event.getAction())
case MotionEvent.ACTION_DOWN:
if (canMove)
checkTouchingTarget(event);
else
if (mOnSeekBarChangeListener != null)
mOnSeekBarChangeListener.onError();
break;
case MotionEvent.ACTION_MOVE:
if (isTouchLegal)
int tempProgress = (int) clamp((int) event.getRawX() - getLeft());
if (tempProgress == progress)
break;
progress = tempProgress;
long currentTime = System.currentTimeMillis();
if (currentTime - mLastTime < 10)
// 刷新 FPS 不超过 20 fps
break;
mLastTime = currentTime;
invalidate(); // 在UI线程中使用 刷新View
if (mOnSeekBarChangeListener != null)
mOnSeekBarChangeListener.onProgress((float) progress / coefficient);
break;
case MotionEvent.ACTION_UP:
invalidate();
break;
return true;
/**
* if touch , seekBar Thumb Animation
*/
private void checkTouchingTarget(MotionEvent event)
if (isTouchingTarget(event))
postInvalidate();
public void setMaxProgress(int maxProgress)
this.maxProgress = maxProgress * coefficient;
/**
* 判断是否 touch 在 seekBar thumb 上
*
* @param event
* @return
*/
private boolean isTouchingTarget(MotionEvent event)
float location = progressPosition + getLeft();
isTouchLegal = event.getRawX() > location - DEFAULT_TOUCH_TARGET_SIZE
&& event.getRawX() < location + DEFAULT_TOUCH_TARGET_SIZE;
return isTouchLegal;
/**
* return progress
* -maxProgress minProgress maxProgress
* \------------------------0---------------------------\
* min center touch-->\ max
* (min center touch max are positions in the screen)
* touch progress = (touch - center) / (max - center) * maxProgress;
*/
private float clamp(int value)
int centerX = getWidth() / 2;
float min = centerX - width / 2;// the start point
float max = centerX + width / 2;// the end point
if (value > centerX)
if (value >= max)
return maxProgress;
else
return (int) ((maxProgress - minProgress) * (value - centerX) / (width / 2f));
else if (value < centerX)
if (value <= min)
return -maxProgress;
else
return (int) ((maxProgress - minProgress) * (value - centerX) / (width / 2f));
else
return minProgress;
public interface OnSeekBarChangeListener
void onProgress(float progress);
void onError();
如何在SeekBar上旋转TextView?
我想在搜索栏上旋转文本视图。活动开放时,我将拇指放在中间。
[如果拇指是中心文本视图,则显示为平坦,但如果拇指向左滑动,则文本视图向左旋转,如果拇指向右滑动,则文本视图向右旋转。
答案
您可以在OnSeekChangeListener中使用以下代码
if(progress<=50){
textView.setRotation((-90*(50-progress))/50);
}else{
textView.setRotation((90*(progress-50))/50);
}
以上是关于正负、中间向两侧滑动的seekbar的主要内容,如果未能解决你的问题,请参考以下文章