近期做项目需要实现类似车辆控制音量加减的回弹开关,实现对监控zoom的控制。具体效果如下图。
代码已付上。感觉可用点个赞吧。
效果如图
u4cbh-gqaiw.gif
代码如下
/**
* zoom view
*
* @author zhj
*/
public class ZoomView extends View {
/**
* 画笔
*/
private Paint paint;
/**
* 点
*/
private Point mRockerPosition, mCenterPoint;
/**
* bitmap
*/
private Bitmap mAreaBitmap, mThumbBitmap;
/**
* size
*/
private int mHeight, mWidth, mThumbWidth, mThumbHeight, distance;
/**
* 动作
*/
private int action;
private OnZoomChangeListener changeListener;
public ZoomView(Context context, AttributeSet attrs) {
super(context, attrs);
// 移动区域画笔
paint = new Paint();
paint.setAntiAlias(true);
// 中心点
mCenterPoint = new Point();
mRockerPosition = new Point();
mAreaBitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.ic_video_zoom_bg);
mThumbBitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.ic_video_zoom_contrl);
mHeight = mAreaBitmap.getHeight();
mWidth = mAreaBitmap.getWidth();
mThumbWidth = mThumbBitmap.getWidth();
mThumbHeight = mThumbBitmap.getHeight();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measureWidth, measureHeight;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY) {
measureWidth = widthSize;
} else {
measureWidth = mWidth;
}
if (heightMode == MeasureSpec.EXACTLY) {
measureHeight = heightSize;
} else {
measureHeight = mHeight;
}
setMeasuredDimension(measureWidth, measureHeight);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int cx = getMeasuredWidth() / 2;
int cy = getMeasuredHeight() / 2;
// 中心点
mCenterPoint.set(cx, cy);
if (0 == mRockerPosition.x || 0 == mRockerPosition.y) {
mRockerPosition.set(mCenterPoint.x, mCenterPoint.y);
}
canvas.drawBitmap(mAreaBitmap, mCenterPoint.x - (mWidth >> 1),
mCenterPoint.y - (mHeight >> 1), paint);
canvas.drawBitmap(mThumbBitmap, mRockerPosition.x - (mThumbWidth >> 1),
mRockerPosition.y - (mThumbHeight >> 1), paint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
action = -1;
break;
case MotionEvent.ACTION_MOVE:
mRockerPosition = getRockerPositionPoint(mCenterPoint,
new Point((int) event.getX(), (int) event.getY()));
moveRocker(mRockerPosition.x, mRockerPosition.y);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (changeListener != null && action != -1) {
changeListener.onZoom(false, action);
}
moveRocker(mCenterPoint.x, mCenterPoint.y);
break;
default:
break;
}
return true;
}
/**
* 获取摇杆实际要显示的位置(点)
*
* @param centerPoint 中心点
* @param touchPoint 触摸点
* @return 摇杆实际显示的位置(点)
*/
private Point getRockerPositionPoint(Point centerPoint, Point touchPoint) {
int tempHeight = getMeasuredHeight();
if (tempHeight > mHeight) {
tempHeight = mHeight;
}
distance = tempHeight / 4;
int y = touchPoint.y;
if (y < centerPoint.y - tempHeight / 2 + mThumbHeight / 2) {
y = centerPoint.y - tempHeight / 2 + mThumbHeight / 2;
}
if (y <= 0) {
y = 1;
}
if (y >= centerPoint.y + tempHeight / 2 - mThumbHeight / 2) {
y = centerPoint.y + tempHeight / 2 - mThumbHeight / 2;
}
int state = -1;
if (y < centerPoint.y - distance) {
state = 0;
} else if (y > centerPoint.y + distance) {
state = 1;
}
if (changeListener != null) {
if (state != -1 && action != state) {
action = state;
changeListener.onZoom(true, action);
}
}
return new Point(centerPoint.x, y);
}
/**
* 移动摇杆到指定位置
*
* @param x x坐标
* @param y y坐标
*/
private void moveRocker(float x, float y) {
mRockerPosition.set((int) x, (int) y);
invalidate();
}
/**
* change
*
* @param changeListener
*/
public void setChangeListener(OnZoomChangeListener changeListener) {
this.changeListener = changeListener;
}
/**
* zoom
*/
public interface OnZoomChangeListener {
/**
* zoom 改变
*
* @param start s
* @param action a
*/
void onZoom(boolean start, int action);
}
}
资源文件
ic_video_zoom_bg.png ic_video_zoom_contrl.png
网友评论