packagecom.example.lb.lbrocker;
importandroid.content.Context;
importandroid.graphics.Bitmap;
importandroid.graphics.BitmapFactory;
importandroid.graphics.Canvas;
importandroid.graphics.PointF;
importandroid.graphics.Rect;
importandroid.util.AttributeSet;
importandroid.util.Log;
importandroid.view.MotionEvent;
importandroid.view.View;
importandroid.view.ViewTreeObserver;
public classRockerView extendsView {
//固定摇杆背景圆形的X,Y坐标以及半径private floatmRockerBg_X;
private floatmRockerBg_Y;
private floatmRockerBg_R;
//摇杆的X,Y坐标以及摇杆的半径private floatmRockerBtn_X;
private floatmRockerBtn_Y;
private floatmRockerBtn_R;
privateBitmap mBmpRockerBg;
privateBitmap mBmpRockerBtn;
privatePointF mCenterPoint;
//按下的确定标志位private booleanmRockerSure;
publicRockerView(Context context, AttributeSet attrs) {
super(context, attrs);
//TODO Auto-generated constructor stub// 获取bitmapmBmpRockerBg= BitmapFactory.decodeResource(context.getResources(), R.drawable.rocker_bg);
mBmpRockerBtn= BitmapFactory.decodeResource(context.getResources(), R.drawable.rocker_btn);
getViewTreeObserver().addOnPreDrawListener(newViewTreeObserver.OnPreDrawListener() {
// 调用该方法时可以获取view实际的宽getWidth()和高getHeight()@Overridepublic booleanonPreDraw() {
//TODO Auto-generated method stubgetViewTreeObserver().removeOnPreDrawListener(this);
Log.e("RockerView", getWidth() + "/"+ getHeight());
mCenterPoint= newPointF(getWidth() / 2, getHeight() / 2);
mRockerBg_X= mCenterPoint.x;
mRockerBg_Y= mCenterPoint.y;
mRockerBtn_X= mCenterPoint.x;
mRockerBtn_Y= mCenterPoint.y;
//确定View的边框大小,按钮和背景的比例floattmp_Bg = mBmpRockerBg.getWidth() / (float)(mBmpRockerBg.getWidth()*2+ mBmpRockerBtn.getWidth());
mRockerBg_R= tmp_Bg * getWidth() / 2;
floattmp_Btn = mBmpRockerBtn.getWidth()/ (float)(mBmpRockerBg.getWidth()*2+ mBmpRockerBtn.getWidth());
mRockerBtn_R=tmp_Btn* getWidth() / 2;
return true;
}
});
newThread(newRunnable() {
@Overridepublic voidrun() {
//TODO Auto-generated method stubwhile(true){
//系统调用onDraw方法刷新画面RockerView.this.postInvalidate();
try{
Thread.sleep(20);
} catch(InterruptedException e) {
//TODO Auto-generated catch blocke.printStackTrace();
}
}
}
}).start();
}
@Overrideprotected voidonDraw(Canvas canvas) {
//TODO Auto-generated method stubsuper.onDraw(canvas);
canvas.drawBitmap(mBmpRockerBg, null,
newRect((int) (mRockerBg_X- mRockerBg_R),
(int) (mRockerBg_Y- mRockerBg_R),
(int) (mRockerBg_X+ mRockerBg_R),
(int) (mRockerBg_Y+ mRockerBg_R)),
null);
canvas.drawBitmap(mBmpRockerBtn, null,
newRect((int) (mRockerBtn_X- mRockerBtn_R),
(int) (mRockerBtn_Y- mRockerBtn_R),
(int) (mRockerBtn_X+ mRockerBtn_R),
(int) (mRockerBtn_Y+ mRockerBtn_R)),
null);
}
@Overridepublic booleanonTouchEvent(MotionEvent event) {
//TODO Auto-generated method stubif(event.getAction() == MotionEvent.ACTION_DOWN){
//当点触屏幕且在圆圈内if(Math.sqrt(Math.pow((mRockerBg_X- (int) event.getX()), 2) + Math.pow((mRockerBg_Y- (int) event.getY()), 2)) <= mRockerBg_R) {
mRockerBtn_X= (int) event.getX();
mRockerBtn_Y= (int) event.getY();
mRockerBg_X= (int) event.getX();
mRockerBg_Y= (int) event.getY();
mRockerSure=true;
}
}
else if( event.getAction() == MotionEvent.ACTION_MOVE&&mRockerSure) {
//当触点滑动且之前触点在圆圈内// 当触屏区域不在活动范围内if(Math.sqrt(Math.pow((mRockerBg_X- (int) event.getX()), 2) + Math.pow((mRockerBg_Y- (int) event.getY()), 2)) >= mRockerBg_R) {
//得到摇杆与触屏点所形成的角度doubletempRad = getRad(mRockerBg_X, mRockerBg_Y, event.getX(), event.getY());
//保证内部小圆运动的长度限制getXY(mRockerBg_X, mRockerBg_Y, mRockerBg_R, tempRad);
} else{//如果小球中心点小于活动区域则随着用户触屏点移动即可mRockerBtn_X= (int) event.getX();
mRockerBtn_Y= (int) event.getY();
}
if(mRockerChangeListener!= null) {
/*//若是需要限定十字方向则不要不需注释这段话if(Math.abs(mRockerBtn_X - mRockerBg_X)>Math.abs(mRockerBtn_Y - mRockerBg_Y)){mRockerBtn_Y = mRockerBg_Y;}else{mRockerBtn_X = mRockerBg_X;}*/mRockerChangeListener.report(mRockerBtn_X- mRockerBg_X, mRockerBtn_Y-mRockerBg_Y);
}
} else if(event.getAction() == MotionEvent.ACTION_UP) {
//当释放按键时摇杆要恢复摇杆的位置为初始位置mRockerBtn_X= mCenterPoint.x;
mRockerBtn_Y= mCenterPoint.y;
mRockerBg_X= mCenterPoint.x;
mRockerBg_Y= mCenterPoint.y;
mRockerSure=false;
if(mRockerChangeListener!= null) {
mRockerChangeListener.report(0, 0);
}
}
return true;
}
public doublegetRad(floatpx1, floatpy1, floatpx2, floatpy2) {
//得到两点X的距离floatx = px2 - px1;
//得到两点Y的距离floaty = py1 - py2;
//算出斜边长floatxie = (float) Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
//得到这个角度的余弦值(通过三角函数中的定理 :邻边/斜边=角度余弦值)floatcosAngle = x / xie;
//通过反余弦定理获取到其角度的弧度floatrad = (float) Math.acos(cosAngle);
//注意:当触屏的位置Y坐标
rad = -rad;
}
returnrad;
}
/****@paramR圆周运动的旋转点*@paramcenterX旋转点X*@paramcenterY旋转点Y*@paramrad旋转的弧度*/public voidgetXY(floatcenterX, floatcenterY, floatR, doublerad) {
//获取圆周运动的X坐标mRockerBtn_X= (float) (R * Math.cos(rad)) + centerX;
//获取圆周运动的Y坐标mRockerBtn_Y= (float) (R * Math.sin(rad)) + centerY;
}
public floatgetR(){
returnmRockerBg_R;
}
RockerChangeListener mRockerChangeListener= null;
public voidsetRockerChangeListener(RockerChangeListener rockerChangeListener) {
mRockerChangeListener= rockerChangeListener;
}
public interfaceRockerChangeListener {
public voidreport(floatx, floaty);
}
}