类名:VerticalSeekBar
public class VerticalSeekBar extends SeekBar
{
private boolean mIsDragging;
private float mTouchDownY;
private int mScaledTouchSlop;
private boolean isInScrollingContainer = false;
public boolean isInScrollingContainer()
{
return isInScrollingContainer;
}
public void setInScrollingContainer(boolean isInScrollingContainer)
{
this.isInScrollingContainer = isInScrollingContainer;
}
float mTouchProgressOffset;
public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
public VerticalSeekBar(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public VerticalSeekBar(Context context)
{
super(context);
}
@Override
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());
}
@Override
protected synchronized void onDraw(Canvas canvas)
{
//顺针旋转90度,
canvas.rotate(90);
canvas.translate(0, -getWidth());
//逆时针旋转90度
//canvas.rotate(-90);
//canvas.translate(-getHeight(), 0);//以原点纵坐标设置为负(滑块高度)
super.onDraw(canvas);
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
if (!isEnabled())
{
return false;
}
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN://按下
if (isInScrollingContainer())
{
mTouchDownY = event.getY();
}
else
{
setPressed(true);
invalidate();
onStartTrackingTouch();
trackTouchEvent(event);
attemptClaimDrag();
onSizeChanged(getWidth(), getHeight(), 0, 0);
}
break;
case MotionEvent.ACTION_MOVE://移动
if (mIsDragging)
{
trackTouchEvent(event);
}
else
{
final float y = event.getY();
if (Math.abs(y - mTouchDownY) > mScaledTouchSlop)
{
setPressed(true);
invalidate();
onStartTrackingTouch();
trackTouchEvent(event);
attemptClaimDrag();
}
}
onSizeChanged(getWidth(), getHeight(), 0, 0);
break;
case MotionEvent.ACTION_UP://抬起
if (mIsDragging)
{
trackTouchEvent(event);
onStopTrackingTouch();
setPressed(false);
}
else
{
onStartTrackingTouch();
trackTouchEvent(event);
onStopTrackingTouch();
}
onSizeChanged(getWidth(), getHeight(), 0, 0);
invalidate();
break;
}
return true;
}
private void trackTouchEvent(MotionEvent event)
{
final int height = getHeight();
final int top = getPaddingTop();
final int bottom = getPaddingBottom();
final int available = height - top - bottom;
int y = (int) event.getY();
float scale;
float progress = 0;
if (y > height - bottom)
{
scale = 0.0f;
}
else if (y < top)
{
scale = 1.0f;
}
else
{
scale = (float) (available - y + top) / (float) available;
progress = mTouchProgressOffset;
}
final int max = getMax();
progress = progress + scale * max;
progress = max - progress;//顺时针旋转90度使用,逆时针旋转90度屏蔽此段
setProgress((int) progress);
}
/**
* 按下
*/
void onStartTrackingTouch()
{
mIsDragging = true;
}
/**
* 松开
*/
void onStopTrackingTouch()
{
mIsDragging = false;
}
private void attemptClaimDrag()
{
ViewParent p = getParent();
if (p != null)
{
p.requestDisallowInterceptTouchEvent(true);
}
}
@Override
public synchronized void setProgress(int progress)
{
super.setProgress(progress);
onSizeChanged(getWidth(), getHeight(), 0, 0);
}
}
XML中:
<TextView
android:id="@+id/textview1"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:text="0" />
<com.example.项目名.VerticalSeekBar
android:id="@+id/verticalSeekBar"
android:layout_width="wrap_content"
android:layout_height="200dp"/>
在Activity中使用:
private VerticalSeekBar verticalSeekBar = null;
verticalSeekBar = (VerticalSeekBar)findViewById(R.id.verticalSeekBar);
verticalSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener()
{
@Override
public void onStopTrackingTouch(SeekBar seekBar){}
@Override
public void onStartTrackingTouch(SeekBar seekBar){}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser)
{
TextView tv= (TextView)findViewById(R.id.textview1);
tv.setText(Integer.toString(progress));
}
});
PS:类中设置的是滑块控件顺时针旋转90度。
如图,白框为屏幕区域,红色为控件,按照原点逆时针旋转90度后,已经不在屏幕显示区域了,需要将控件平移。
//getHeight()为控件高度,getWidth()为控件宽度
顺时针旋转90度:
canvas.rotate(90);
canvas.translate(0, -getWidth());//右移一个控件宽度
progress = max - progress;
逆时针旋转90度:canvas.rotate(-90);//逆时针旋转90度
canvas.translate(-getHeight(), 0);//下移一个控件高度