Mainly includes three parts, respectively is the calling class, touch handler class, utility class.
Touch handler class: AppSingleRocker
package com.seuic;
import com.seuic.util.MathUtils;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PorterDuff.Mode;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;
public class AppSingleRocker extends SurfaceView implements Callback{
private SurfaceHolder mHolder;
private Paint mPaint;
public Point mRockerPosition; // Rocker position
private Point mCtrlPoint = new Point(80, 80);// Rocker starting position
private int mRudderRadius = 20;//Rocker arm radius
private int mWheelRadius = 60;//Rocker range radius
int isHide = 0;
private SingleRudderListener listener = null; //事件回调接口
public static final int ACTION_RUDDER = 1, ACTION_ATTACK_DEVICEMOVE = 2, ACTION_STOP = 3, ACTION_ATTACK_CAMERAMOVE = 4;
public AppSingleRocker(Context context) {
super(context);
this.setKeepScreenOn(true);
mHolder = getHolder();
mHolder.addCallback(this);
mPaint = new Paint();
mPaint.setColor(Color.GREEN);
mPaint.setAntiAlias(true);//抗锯齿
mRockerPosition = new Point(mCtrlPoint);
setFocusable(true);
setFocusableInTouchMode(true);
setZOrderOnTop(true);
mHolder.setFormat(PixelFormat.TRANSPARENT);//设置背景透明
}
//回调接口
public interface SingleRudderListener {
void onSteeringWheelChanged(int action,int angle);
}
//设置回调接口
public void setSingleRudderListener(SingleRudderListener rockerListener) {
listener = rockerListener;
}
int len;
@Override
public boolean onTouchEvent(MotionEvent event) {
try {
if (isHide == 0) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
len = MathUtils.getLength(mCtrlPoint.x, mCtrlPoint.y, event.getX(), event.getY());
//如果屏幕接触点不在摇杆挥动范围内,则不处理
if(len >mWheelRadius) {
return true;
}
break;
case MotionEvent.ACTION_MOVE:
len = MathUtils.getLength(mCtrlPoint.x, mCtrlPoint.y, event.getX(), event.getY());
if(len <= mWheelRadius) {
//如果手指在摇杆活动范围内,则摇杆处于手指触摸位置
mRockerPosition.set((int)event.getX(), (int)event.getY());
}else{
//设置摇杆位置,使其处于手指触摸方向的 摇杆活动范围边缘
mRockerPosition = MathUtils.getBorderPoint(mCtrlPoint, new Point((int)event.getX(), (int)event.getY()), mWheelRadius);
}
if(listener != null) {
float radian = MathUtils.getRadian(mCtrlPoint, new Point((int)event.getX(), (int)event.getY()));
listener.onSteeringWheelChanged(ACTION_RUDDER, getAngleCouvert(radian));
}
break;
case MotionEvent.ACTION_UP:
mRockerPosition = new Point(mCtrlPoint);
listener.onSteeringWheelChanged(ACTION_STOP, 0);
break;
}
Canvas_OK();
Thread.sleep(60);
}else {
Thread.sleep(200);
}
} catch (Exception e) {
}
return true;
}
//获取摇杆偏移角度 0-360°
private int getAngleCouvert(float radian) {
int tmp = (int)Math.round(radian/Math.PI*180);
if(tmp < 0) {
return -tmp;
}else{
return 180 + (180 - tmp);
}
}
public void surfaceCreated(SurfaceHolder holder) {
Canvas_OK();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
}
// 设置是否隐藏
public void Hided(int opt)
{
isHide = opt;
Canvas_OK();
}
//绘制图像
public void Canvas_OK(){
Canvas canvas = null;
try {
canvas = mHolder.lockCanvas();
canvas.drawColor(Color.TRANSPARENT,Mode.CLEAR);//清除屏幕
mPaint.setColor(Color.CYAN);
mPaint.setAlpha(100);
canvas.drawCircle(mCtrlPoint.x, mCtrlPoint.y, mWheelRadius, mPaint);//绘制范围
mPaint.setColor(Color.RED);
mPaint.setAlpha(100);
canvas.drawCircle(mRockerPosition.x, mRockerPosition.y, mRudderRadius, mPaint);//绘制摇杆
} catch (Exception e) {
e.printStackTrace();
} finally {
if(canvas != null) {
mHolder.unlockCanvasAndPost(canvas);
}
}
}
}
utility class:MathUtils
package com.seuic.util;
import android.graphics.Point;
public class MathUtils {
//获取两点间直线距离
public static int getLength(float x1,float y1,float x2,float y2) {
return (int)Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2));
}
/**
* 获取线段上某个点的坐标,长度为a.x - cutRadius
* @param a 点A
* @param b 点B
* @param cutRadius 截断距离
* @return 截断点
*/
public static Point getBorderPoint(Point a, Point b,int cutRadius) {
float radian = getRadian(a, b);
return new Point(a.x + (int)(cutRadius * Math.cos(radian)), a.x + (int)(cutRadius * Math.sin(radian)));
}
//获取水平线夹角弧度
public static float getRadian (Point a, Point b) {
float lenA = b.x-a.x;
float lenB = b.y-a.y;
float lenC = (float)Math.sqrt(lenA*lenA+lenB*lenB);
float ang = (float)Math.acos(lenA/lenC);
ang = ang * (b.y < a.y ? -1 : 1);
return ang;
}
}
calling class:SingleRocker
package com.seuic;
import com.seuic.AppSingleRocker.SingleRudderListener;
import android.os.Bundle;
import android.util.Log;
import android.widget.RelativeLayout;
import android.app.Activity;
public class SingleRocker extends Activity {
RelativeLayout Parent;
AppSingleRocker appSingleRocker;
public static final String Main = "SingleRocker";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Parent = new RelativeLayout(this);
RelativeLayout.LayoutParams RockerCanvasParams = new RelativeLayout.LayoutParams(160,160);
RockerCanvasParams.addRule(RelativeLayout.CENTER_VERTICAL);
appSingleRocker = new AppSingleRocker(this);
Parent.addView(appSingleRocker,RockerCanvasParams);
setContentView(Parent);
appSingleRocker.setSingleRudderListener(new SingleRudderListener() {
@Override
public void onSteeringWheelChanged(int action, int angle) {
Log.e(Main, angle+"");
}
});
}
source address:
http://download.csdn.net/download/jwzhangjie/5184324