Android joystick,安卓模拟摇杆

news/发布时间2024/4/29 4:26:29

安卓模拟游戏摇杆,android实现自定义view

参考文章:https://www.jianshu.com/p/96c982d41623 ,原文部分内容不全。

attrs.xml

<resources><declare-styleable name="RockerView"><attr name="areaBackground" format="color|reference" /><attr name="rockerBackground" format="color|reference" /><attr name="rockerRadius" format="dimension" /><attr name="rockerScale" format="float"/><attr name="rockerSpeedLevel" format="dimension" /><attr name="rockerCallBackMode" format="dimension" /></declare-styleable>
</resources>

RockerView.java

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;import com.zony.hello.R;import java.util.logging.Level;/*** Created by jinkia on 2016/9/30.* 摇杆控件*/
public class RockerView extends View {private static final String TAG = "RockerView";private static final int DEFAULT_SIZE = 400;private static final float DEFAULT_ROCKER_SCALE = 0.5f;//默认半径为背景的1/2private Paint mAreaBackgroundPaint;private Paint mRockerPaint;private Point mRockerPosition;private Point mCenterPoint;private int mAreaRadius;private float mRockerScale;private int mRockerRadius;private CallBackMode mCallBackMode = CallBackMode.CALL_BACK_MODE_MOVE;private OnAngleChangeListener mOnAngleChangeListener;private OnShakeListener mOnShakeListener;private OnDistanceLevelListener mOnDistanceLevelListener;private DirectionMode mDirectionMode;private Direction tempDirection = Direction.DIRECTION_CENTER;private float lastDistance = 0;private boolean hasCall = false;private float baseDistance = 0;private int mDistanceLevel = 10;//分成10分// 角度private static final double ANGLE_0 = 0;private static final double ANGLE_360 = 360;// 360°水平方向平分2份的边缘角度private static final double ANGLE_HORIZONTAL_2D_OF_0P = 90;private static final double ANGLE_HORIZONTAL_2D_OF_1P = 270;// 360°垂直方向平分2份的边缘角度private static final double ANGLE_VERTICAL_2D_OF_0P = 0;private static final double ANGLE_VERTICAL_2D_OF_1P = 180;// 360°平分4份的边缘角度private static final double ANGLE_4D_OF_0P = 0;private static final double ANGLE_4D_OF_1P = 90;private static final double ANGLE_4D_OF_2P = 180;private static final double ANGLE_4D_OF_3P = 270;// 360°平分4份的边缘角度(旋转45度)private static final double ANGLE_ROTATE45_4D_OF_0P = 45;private static final double ANGLE_ROTATE45_4D_OF_1P = 135;private static final double ANGLE_ROTATE45_4D_OF_2P = 225;private static final double ANGLE_ROTATE45_4D_OF_3P = 315;// 360°平分8份的边缘角度private static final double ANGLE_8D_OF_0P = 22.5;private static final double ANGLE_8D_OF_1P = 67.5;private static final double ANGLE_8D_OF_2P = 112.5;private static final double ANGLE_8D_OF_3P = 157.5;private static final double ANGLE_8D_OF_4P = 202.5;private static final double ANGLE_8D_OF_5P = 247.5;private static final double ANGLE_8D_OF_6P = 292.5;private static final double ANGLE_8D_OF_7P = 337.5;// 摇杆可移动区域背景private static final int AREA_BACKGROUND_MODE_PIC = 0;private static final int AREA_BACKGROUND_MODE_COLOR = 1;private static final int AREA_BACKGROUND_MODE_XML = 2;private static final int AREA_BACKGROUND_MODE_DEFAULT = 3;private int mAreaBackgroundMode = AREA_BACKGROUND_MODE_DEFAULT;private Bitmap mAreaBitmap;private int mAreaColor;// 摇杆背景private static final int ROCKER_BACKGROUND_MODE_PIC = 4;private static final int ROCKER_BACKGROUND_MODE_COLOR = 5;private static final int ROCKER_BACKGROUND_MODE_XML = 6;private static final int ROCKER_BACKGROUND_MODE_DEFAULT = 7;private int mRockerBackgroundMode = ROCKER_BACKGROUND_MODE_DEFAULT;private Bitmap mRockerBitmap;private int mRockerColor;public RockerView(Context context, AttributeSet attrs) {super(context, attrs);// 获取自定义属性initAttribute(context, attrs);if (isInEditMode()) {}// 移动区域画笔mAreaBackgroundPaint = new Paint();mAreaBackgroundPaint.setAntiAlias(true);// 摇杆画笔mRockerPaint = new Paint();mRockerPaint.setAntiAlias(true);// 中心点mCenterPoint = new Point();// 摇杆位置mRockerPosition = new Point();}/*** 获取属性** @param context context* @param attrs   attrs*/private void initAttribute(Context context, AttributeSet attrs) {TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RockerView);// 可移动区域背景Drawable areaBackground = typedArray.getDrawable(R.styleable.RockerView_areaBackground);if (null != areaBackground) {// 设置了背景if (areaBackground instanceof BitmapDrawable) {// 设置了一张图片mAreaBitmap = ((BitmapDrawable) areaBackground).getBitmap();mAreaBackgroundMode = AREA_BACKGROUND_MODE_PIC;} else if (areaBackground instanceof GradientDrawable) {// XMLmAreaBitmap = drawable2Bitmap(areaBackground);mAreaBackgroundMode = AREA_BACKGROUND_MODE_XML;} else if (areaBackground instanceof ColorDrawable) {// 色值mAreaColor = ((ColorDrawable) areaBackground).getColor();mAreaBackgroundMode = AREA_BACKGROUND_MODE_COLOR;} else {// 其他形式mAreaBackgroundMode = AREA_BACKGROUND_MODE_DEFAULT;}} else {// 没有设置背景mAreaBackgroundMode = AREA_BACKGROUND_MODE_DEFAULT;}// 摇杆背景Drawable rockerBackground = typedArray.getDrawable(R.styleable.RockerView_rockerBackground);if (null != rockerBackground) {// 设置了摇杆背景if (rockerBackground instanceof BitmapDrawable) {// 图片mRockerBitmap = ((BitmapDrawable) rockerBackground).getBitmap();mRockerBackgroundMode = ROCKER_BACKGROUND_MODE_PIC;} else if (rockerBackground instanceof GradientDrawable) {// XMLmRockerBitmap = drawable2Bitmap(rockerBackground);mRockerBackgroundMode = ROCKER_BACKGROUND_MODE_XML;} else if (rockerBackground instanceof ColorDrawable) {// 色值mRockerColor = ((ColorDrawable) rockerBackground).getColor();mRockerBackgroundMode = ROCKER_BACKGROUND_MODE_COLOR;} else {// 其他形式mRockerBackgroundMode = ROCKER_BACKGROUND_MODE_DEFAULT;}} else {// 没有设置摇杆背景mRockerBackgroundMode = ROCKER_BACKGROUND_MODE_DEFAULT;}// 摇杆半径mRockerScale = typedArray.getFloat(R.styleable.RockerView_rockerScale, DEFAULT_ROCKER_SCALE);//距离级别mDistanceLevel = typedArray.getInt(R.styleable.RockerView_rockerSpeedLevel, 10);//回调模式mCallBackMode = getCallBackMode(typedArray.getInt(R.styleable.RockerView_rockerCallBackMode, 0));typedArray.recycle();}@Overrideprotected 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) {// 具体的值和match_parentmeasureWidth = widthSize;} else {// wrap_contentmeasureWidth = DEFAULT_SIZE;}if (heightMode == MeasureSpec.EXACTLY) {measureHeight = heightSize;} else {measureHeight = DEFAULT_SIZE;}setMeasuredDimension(measureWidth, measureHeight);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int measuredWidth = getMeasuredWidth();int measuredHeight = getMeasuredHeight();int cx = measuredWidth / 2;int cy = measuredHeight / 2;// 中心点mCenterPoint.set(cx, cy);// 可移动区域的半径mAreaRadius = (measuredWidth <= measuredHeight) ? (int) (cx / (mRockerScale + 1)) : (int) (cy / (mRockerScale + 1));mRockerRadius = (int) (mAreaRadius * mRockerScale);// 摇杆位置if (0 == mRockerPosition.x || 0 == mRockerPosition.y) {mRockerPosition.set(mCenterPoint.x, mCenterPoint.y);}// 画可移动区域if (AREA_BACKGROUND_MODE_PIC == mAreaBackgroundMode || AREA_BACKGROUND_MODE_XML == mAreaBackgroundMode) {// 图片Rect src = new Rect(0, 0, mAreaBitmap.getWidth(), mAreaBitmap.getHeight());Rect dst = new Rect(mCenterPoint.x - mAreaRadius, mCenterPoint.y - mAreaRadius, mCenterPoint.x + mAreaRadius, mCenterPoint.y + mAreaRadius);canvas.drawBitmap(mAreaBitmap, src, dst, mAreaBackgroundPaint);} else if (AREA_BACKGROUND_MODE_COLOR == mAreaBackgroundMode) {// 色值mAreaBackgroundPaint.setColor(mAreaColor);canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, mAreaRadius, mAreaBackgroundPaint);} else {// 其他或者未设置mAreaBackgroundPaint.setColor(Color.GRAY);canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, mAreaRadius, mAreaBackgroundPaint);}// 画摇杆if (ROCKER_BACKGROUND_MODE_PIC == mRockerBackgroundMode || ROCKER_BACKGROUND_MODE_XML == mRockerBackgroundMode) {// 图片Rect src = new Rect(0, 0, mRockerBitmap.getWidth(), mRockerBitmap.getHeight());Rect dst = new Rect(mRockerPosition.x - mRockerRadius, mRockerPosition.y - mRockerRadius, mRockerPosition.x + mRockerRadius, mRockerPosition.y + mRockerRadius);canvas.drawBitmap(mRockerBitmap, src, dst, mRockerPaint);} else if (ROCKER_BACKGROUND_MODE_COLOR == mRockerBackgroundMode) {// 色值mRockerPaint.setColor(mRockerColor);canvas.drawCircle(mRockerPosition.x, mRockerPosition.y, mRockerRadius, mRockerPaint);} else {// 其他或者未设置mRockerPaint.setColor(Color.RED);canvas.drawCircle(mRockerPosition.x, mRockerPosition.y, mRockerRadius, mRockerPaint);}}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:// 按下// 回调 开始callBackStart();case MotionEvent.ACTION_MOVE:// 移动float moveX = event.getX();float moveY = event.getY();baseDistance = mAreaRadius + 2;Log.d("baseDistance", baseDistance + "");mRockerPosition = getRockerPositionPoint(mCenterPoint, new Point((int) moveX, (int) moveY), mAreaRadius + mRockerRadius, mRockerRadius);moveRocker(mRockerPosition.x, mRockerPosition.y);break;case MotionEvent.ACTION_UP:// 抬起case MotionEvent.ACTION_CANCEL:// 移出区域// 回调 结束callBackFinish();if (mOnShakeListener != null) {mOnShakeListener.direction(Direction.DIRECTION_CENTER);}float upX = event.getX();float upY = event.getY();moveRocker(mCenterPoint.x, mCenterPoint.y);break;}return true;}/*** 获取摇杆实际要显示的位置(点)** @param centerPoint  中心点* @param touchPoint   触摸点* @param regionRadius 摇杆可活动区域半径* @param rockerRadius 摇杆半径* @return 摇杆实际显示的位置(点)*/private Point getRockerPositionPoint(Point centerPoint, Point touchPoint, float regionRadius, float rockerRadius) {// 两点在X轴的距离float lenX = (float) (touchPoint.x - centerPoint.x);// 两点在Y轴距离float lenY = (float) (touchPoint.y - centerPoint.y);// 两点距离float lenXY = (float) Math.sqrt((double) (lenX * lenX + lenY * lenY));// 计算弧度double radian = Math.acos(lenX / lenXY) * (touchPoint.y < centerPoint.y ? -1 : 1);// 计算角度double angle = radian2Angle(radian);if (lenXY + rockerRadius <= regionRadius) { // 触摸位置在可活动范围内// 回调 返回参数callBack(angle, (int) lenXY);return touchPoint;} else { // 触摸位置在可活动范围以外// 计算要显示的位置int showPointX = (int) (centerPoint.x + (regionRadius - rockerRadius) * Math.cos(radian));int showPointY = (int) (centerPoint.y + (regionRadius - rockerRadius) * Math.sin(radian));callBack(angle, (int) Math.sqrt((showPointX - centerPoint.x) * (showPointX - centerPoint.x) + (showPointY - centerPoint.y) * (showPointY - centerPoint.y)));return new Point(showPointX, showPointY);}}/*** 移动摇杆到指定位置** @param x x坐标* @param y y坐标*/private void moveRocker(float x, float y) {mRockerPosition.set((int) x, (int) y);invalidate();}/*** 弧度转角度** @param radian 弧度* @return 角度[0, 360)*/private double radian2Angle(double radian) {double tmp = Math.round(radian / Math.PI * 180);return tmp >= 0 ? tmp : 360 + tmp;}/*** Drawable 转 Bitmap** @param drawable Drawable* @return Bitmap*/private Bitmap drawable2Bitmap(Drawable drawable) {// 取 drawable 的长宽int width = drawable.getIntrinsicWidth();int height = drawable.getIntrinsicHeight();// 取 drawable 的颜色格式Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;// 建立对应 bitmapBitmap bitmap = Bitmap.createBitmap(width, height, config);Canvas canvas = new Canvas(bitmap);drawable.setBounds(0, 0, width, height);drawable.draw(canvas);return bitmap;}/*** 回调* 开始*/private void callBackStart() {tempDirection = Direction.DIRECTION_CENTER;if (null != mOnAngleChangeListener) {mOnAngleChangeListener.onStart();}if (null != mOnShakeListener) {mOnShakeListener.onStart();}}/*** 回调* 返回参数** @param angle 摇动角度*/private void callBack(double angle, float distance) {Log.d("distance", distance + "");if (Math.abs(distance - lastDistance) >= (baseDistance / mDistanceLevel)) {lastDistance = distance;if (null != mOnDistanceLevelListener) {int level = (int) (distance / (baseDistance / mDistanceLevel));mOnDistanceLevelListener.onDistanceLevel(level);}}if (null != mOnAngleChangeListener) {mOnAngleChangeListener.angle(angle);}if (null != mOnShakeListener) {if (CallBackMode.CALL_BACK_MODE_MOVE == mCallBackMode) {switch (mDirectionMode) {case DIRECTION_2_HORIZONTAL:// 左右方向if (ANGLE_0 <= angle && ANGLE_HORIZONTAL_2D_OF_0P > angle || ANGLE_HORIZONTAL_2D_OF_1P <= angle && ANGLE_360 > angle) {// 右mOnShakeListener.direction(Direction.DIRECTION_RIGHT);} else if (ANGLE_HORIZONTAL_2D_OF_0P <= angle && ANGLE_HORIZONTAL_2D_OF_1P > angle) {// 左mOnShakeListener.direction(Direction.DIRECTION_LEFT);}break;case DIRECTION_2_VERTICAL:// 上下方向if (ANGLE_VERTICAL_2D_OF_0P <= angle && ANGLE_VERTICAL_2D_OF_1P > angle) {// 下mOnShakeListener.direction(Direction.DIRECTION_DOWN);} else if (ANGLE_VERTICAL_2D_OF_1P <= angle && ANGLE_360 > angle) {// 上mOnShakeListener.direction(Direction.DIRECTION_UP);}break;case DIRECTION_4_ROTATE_0:// 四个方向if (ANGLE_4D_OF_0P <= angle && ANGLE_4D_OF_1P > angle) {// 右下mOnShakeListener.direction(Direction.DIRECTION_DOWN_RIGHT);} else if (ANGLE_4D_OF_1P <= angle && ANGLE_4D_OF_2P > angle) {// 左下mOnShakeListener.direction(Direction.DIRECTION_DOWN_LEFT);} else if (ANGLE_4D_OF_2P <= angle && ANGLE_4D_OF_3P > angle) {// 左上mOnShakeListener.direction(Direction.DIRECTION_UP_LEFT);} else if (ANGLE_4D_OF_3P <= angle && ANGLE_360 > angle) {// 右上mOnShakeListener.direction(Direction.DIRECTION_UP_RIGHT);}break;case DIRECTION_4_ROTATE_45:// 四个方向 旋转45度if (ANGLE_0 <= angle && ANGLE_ROTATE45_4D_OF_0P > angle || ANGLE_ROTATE45_4D_OF_3P <= angle && ANGLE_360 > angle) {// 右mOnShakeListener.direction(Direction.DIRECTION_RIGHT);} else if (ANGLE_ROTATE45_4D_OF_0P <= angle && ANGLE_ROTATE45_4D_OF_1P > angle) {// 下mOnShakeListener.direction(Direction.DIRECTION_DOWN);} else if (ANGLE_ROTATE45_4D_OF_1P <= angle && ANGLE_ROTATE45_4D_OF_2P > angle) {// 左mOnShakeListener.direction(Direction.DIRECTION_LEFT);} else if (ANGLE_ROTATE45_4D_OF_2P <= angle && ANGLE_ROTATE45_4D_OF_3P > angle) {// 上mOnShakeListener.direction(Direction.DIRECTION_UP);}break;case DIRECTION_8:// 八个方向if (ANGLE_0 <= angle && ANGLE_8D_OF_0P > angle || ANGLE_8D_OF_7P <= angle && ANGLE_360 > angle) {// 右mOnShakeListener.direction(Direction.DIRECTION_RIGHT);} else if (ANGLE_8D_OF_0P <= angle && ANGLE_8D_OF_1P > angle) {// 右下mOnShakeListener.direction(Direction.DIRECTION_DOWN_RIGHT);} else if (ANGLE_8D_OF_1P <= angle && ANGLE_8D_OF_2P > angle) {// 下mOnShakeListener.direction(Direction.DIRECTION_DOWN);} else if (ANGLE_8D_OF_2P <= angle && ANGLE_8D_OF_3P > angle) {// 左下mOnShakeListener.direction(Direction.DIRECTION_DOWN_LEFT);} else if (ANGLE_8D_OF_3P <= angle && ANGLE_8D_OF_4P > angle) {// 左mOnShakeListener.direction(Direction.DIRECTION_LEFT);} else if (ANGLE_8D_OF_4P <= angle && ANGLE_8D_OF_5P > angle) {// 左上mOnShakeListener.direction(Direction.DIRECTION_UP_LEFT);} else if (ANGLE_8D_OF_5P <= angle && ANGLE_8D_OF_6P > angle) {// 上mOnShakeListener.direction(Direction.DIRECTION_UP);} else if (ANGLE_8D_OF_6P <= angle && ANGLE_8D_OF_7P > angle) {// 右上mOnShakeListener.direction(Direction.DIRECTION_UP_RIGHT);}break;default:break;}} else if (CallBackMode.CALL_BACK_MODE_STATE_CHANGE == mCallBackMode) {switch (mDirectionMode) {case DIRECTION_2_HORIZONTAL:// 左右方向if ((ANGLE_0 <= angle && ANGLE_HORIZONTAL_2D_OF_0P > angle || ANGLE_HORIZONTAL_2D_OF_1P <= angle && ANGLE_360 > angle) && tempDirection != Direction.DIRECTION_RIGHT) {// 右tempDirection = Direction.DIRECTION_RIGHT;mOnShakeListener.direction(Direction.DIRECTION_RIGHT);} else if (ANGLE_HORIZONTAL_2D_OF_0P <= angle && ANGLE_HORIZONTAL_2D_OF_1P > angle && tempDirection != Direction.DIRECTION_LEFT) {// 左tempDirection = Direction.DIRECTION_LEFT;mOnShakeListener.direction(Direction.DIRECTION_LEFT);}break;case DIRECTION_2_VERTICAL:// 上下方向if (ANGLE_VERTICAL_2D_OF_0P <= angle && ANGLE_VERTICAL_2D_OF_1P > angle && tempDirection != Direction.DIRECTION_DOWN) {// 下tempDirection = Direction.DIRECTION_DOWN;mOnShakeListener.direction(Direction.DIRECTION_DOWN);} else if (ANGLE_VERTICAL_2D_OF_1P <= angle && ANGLE_360 > angle && tempDirection != Direction.DIRECTION_UP) {// 上tempDirection = Direction.DIRECTION_UP;mOnShakeListener.direction(Direction.DIRECTION_UP);}break;case DIRECTION_4_ROTATE_0:// 四个方向if (ANGLE_4D_OF_0P <= angle && ANGLE_4D_OF_1P > angle && tempDirection != Direction.DIRECTION_DOWN_RIGHT) {// 右下tempDirection = Direction.DIRECTION_DOWN_RIGHT;mOnShakeListener.direction(Direction.DIRECTION_DOWN_RIGHT);} else if (ANGLE_4D_OF_1P <= angle && ANGLE_4D_OF_2P > angle && tempDirection != Direction.DIRECTION_DOWN_LEFT) {// 左下tempDirection = Direction.DIRECTION_DOWN_LEFT;mOnShakeListener.direction(Direction.DIRECTION_DOWN_LEFT);} else if (ANGLE_4D_OF_2P <= angle && ANGLE_4D_OF_3P > angle && tempDirection != Direction.DIRECTION_UP_LEFT) {// 左上tempDirection = Direction.DIRECTION_UP_LEFT;mOnShakeListener.direction(Direction.DIRECTION_UP_LEFT);} else if (ANGLE_4D_OF_3P <= angle && ANGLE_360 > angle && tempDirection != Direction.DIRECTION_UP_RIGHT) {// 右上tempDirection = Direction.DIRECTION_UP_RIGHT;mOnShakeListener.direction(Direction.DIRECTION_UP_RIGHT);}break;case DIRECTION_4_ROTATE_45:// 四个方向 旋转45度if ((ANGLE_0 <= angle && ANGLE_ROTATE45_4D_OF_0P > angle || ANGLE_ROTATE45_4D_OF_3P <= angle && ANGLE_360 > angle) && tempDirection != Direction.DIRECTION_RIGHT) {// 右tempDirection = Direction.DIRECTION_RIGHT;mOnShakeListener.direction(Direction.DIRECTION_RIGHT);} else if (ANGLE_ROTATE45_4D_OF_0P <= angle && ANGLE_ROTATE45_4D_OF_1P > angle && tempDirection != Direction.DIRECTION_DOWN) {// 下tempDirection = Direction.DIRECTION_DOWN;mOnShakeListener.direction(Direction.DIRECTION_DOWN);} else if (ANGLE_ROTATE45_4D_OF_1P <= angle && ANGLE_ROTATE45_4D_OF_2P > angle && tempDirection != Direction.DIRECTION_LEFT) {// 左tempDirection = Direction.DIRECTION_LEFT;mOnShakeListener.direction(Direction.DIRECTION_LEFT);} else if (ANGLE_ROTATE45_4D_OF_2P <= angle && ANGLE_ROTATE45_4D_OF_3P > angle && tempDirection != Direction.DIRECTION_UP) {// 上tempDirection = Direction.DIRECTION_UP;mOnShakeListener.direction(Direction.DIRECTION_UP);}break;case DIRECTION_8:// 八个方向if ((ANGLE_0 <= angle && ANGLE_8D_OF_0P > angle || ANGLE_8D_OF_7P <= angle && ANGLE_360 > angle) && tempDirection != Direction.DIRECTION_RIGHT) {// 右tempDirection = Direction.DIRECTION_RIGHT;mOnShakeListener.direction(Direction.DIRECTION_RIGHT);} else if (ANGLE_8D_OF_0P <= angle && ANGLE_8D_OF_1P > angle && tempDirection != Direction.DIRECTION_DOWN_RIGHT) {// 右下tempDirection = Direction.DIRECTION_DOWN_RIGHT;mOnShakeListener.direction(Direction.DIRECTION_DOWN_RIGHT);} else if (ANGLE_8D_OF_1P <= angle && ANGLE_8D_OF_2P > angle && tempDirection != Direction.DIRECTION_DOWN) {// 下tempDirection = Direction.DIRECTION_DOWN;mOnShakeListener.direction(Direction.DIRECTION_DOWN);} else if (ANGLE_8D_OF_2P <= angle && ANGLE_8D_OF_3P > angle && tempDirection != Direction.DIRECTION_DOWN_LEFT) {// 左下tempDirection = Direction.DIRECTION_DOWN_LEFT;mOnShakeListener.direction(Direction.DIRECTION_DOWN_LEFT);} else if (ANGLE_8D_OF_3P <= angle && ANGLE_8D_OF_4P > angle && tempDirection != Direction.DIRECTION_LEFT) {// 左tempDirection = Direction.DIRECTION_LEFT;mOnShakeListener.direction(Direction.DIRECTION_LEFT);} else if (ANGLE_8D_OF_4P <= angle && ANGLE_8D_OF_5P > angle && tempDirection != Direction.DIRECTION_UP_LEFT) {// 左上tempDirection = Direction.DIRECTION_UP_LEFT;mOnShakeListener.direction(Direction.DIRECTION_UP_LEFT);} else if (ANGLE_8D_OF_5P <= angle && ANGLE_8D_OF_6P > angle && tempDirection != Direction.DIRECTION_UP) {// 上tempDirection = Direction.DIRECTION_UP;mOnShakeListener.direction(Direction.DIRECTION_UP);} else if (ANGLE_8D_OF_6P <= angle && ANGLE_8D_OF_7P > angle && tempDirection != Direction.DIRECTION_UP_RIGHT) {// 右上tempDirection = Direction.DIRECTION_UP_RIGHT;mOnShakeListener.direction(Direction.DIRECTION_UP_RIGHT);}break;default:break;}}}}/*** 回调* 结束*/private void callBackFinish() {tempDirection = Direction.DIRECTION_CENTER;if (null != mOnAngleChangeListener) {mOnAngleChangeListener.onFinish();}if (null != mOnShakeListener) {mOnShakeListener.onFinish();}}/*** 回调模式*/public enum CallBackMode {// 有移动就立刻回调CALL_BACK_MODE_MOVE,// 只有状态变化的时候才回调CALL_BACK_MODE_STATE_CHANGE,//只有状态变化或者距离变化的时候才回调CALL_BACK_MODE_STATE_DISTANCE_CHANGE}/*** 设置回调模式** @param mode 回调模式*/public void setCallBackMode(CallBackMode mode) {mCallBackMode = mode;}/*** 摇杆支持几个方向*/public enum DirectionMode {DIRECTION_2_HORIZONTAL,// 横向 左右两个方向DIRECTION_2_VERTICAL, // 纵向 上下两个方向DIRECTION_4_ROTATE_0, // 四个方向DIRECTION_4_ROTATE_45, // 四个方向 旋转45度DIRECTION_8 // 八个方向}/*** 方向*/public enum Direction {DIRECTION_LEFT, // 左DIRECTION_RIGHT, // 右DIRECTION_UP, // 上DIRECTION_DOWN, // 下DIRECTION_UP_LEFT, // 左上DIRECTION_UP_RIGHT, // 右上DIRECTION_DOWN_LEFT, // 左下DIRECTION_DOWN_RIGHT, // 右下DIRECTION_CENTER // 中间}/*** 添加摇杆摇动角度的监听** @param listener 回调接口*/public void setOnAngleChangeListener(OnAngleChangeListener listener) {mOnAngleChangeListener = listener;}/*** 添加摇动的监听** @param directionMode 监听的方向* @param listener      回调*/public void setOnShakeListener(DirectionMode directionMode, OnShakeListener listener) {mDirectionMode = directionMode;mOnShakeListener = listener;}/*** 添加摇动的距离变化*/public void setOnDistanceLevelListener(OnDistanceLevelListener listener) {mOnDistanceLevelListener = listener;}/*** 摇动方向监听接口*/public interface OnShakeListener {// 开始void onStart();/*** 摇动方向** @param direction 方向*/void direction(Direction direction);// 结束void onFinish();}/*** 摇动角度的监听接口*/public interface OnAngleChangeListener {// 开始void onStart();/*** 摇杆角度变化** @param angle 角度[0,360)*/void angle(double angle);// 结束void onFinish();}/*** 摇动距离*/public interface OnDistanceLevelListener {void onDistanceLevel(int level);}private CallBackMode getCallBackMode(int mode) {switch (mode) {case 0:return CallBackMode.CALL_BACK_MODE_MOVE;case 1:return CallBackMode.CALL_BACK_MODE_STATE_CHANGE;}return mCallBackMode;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/60738626.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

spring 路由安全

岁月何来重头?资料Spring MVC — @RequestMapping原理讲解-1 - 陶庭开 - 博客园 (cnblogs.com) SpringBoot之@Controller和@RequestMapping的实现原理_51CTO博客_controller requestmapping Spring MVC源码解析——HandlerMapping(处理器映射器)_springmvc handlermapping-CSD…

sql学习

-- 学生表CREATE TABLE t_student ( id BIGINT PRIMARY KEY, name VARCHAR(255), gender VARCHAR(255), age INT, address VARCHAR(255), INDEX idx_age (age) …

《比特与瓦特》揭秘防滑黑科技 华为 DriveONE定义未来底盘

亿欧数据显示:2023年,中国新能源汽车销量达950万辆,其中智能电动汽车销量为614万辆,渗透率为65%。预计到2025年,新能源汽车销量将达到1524万辆,智能电动汽车销量将为1220万辆,渗透率达80%。 智能汽车正在走进千家万户,我们已经可以切身体验到驾驶方式的变化。从传统汽车…

快速上手App自动化测试利器,Toast原理解析及操作实例

简介 Toast 是一种轻量级的消息提示,常常以小弹框的形式出现,一般出现 1 到 2 秒会自动消失,可以出现在屏幕上中下任意位置。 Toast具有如下的特点:无法被点击,不同于 Dialog,永远不会获得焦点。 Toast 显示的时间有限,Toast 会根据用户设置的显示时间后自动消失 是系统…

读算法的陷阱:超级平台、算法垄断与场景欺骗笔记15_虚拟助手

读算法的陷阱:超级平台、算法垄断与场景欺骗笔记15_虚拟助手1. 虚拟助手 1.1. 站在全球视角,这些公司是:亚马逊、脸书、谷歌和苹果 1.1.1. 苹果的Siri 1.1.2. 亚马逊的Alexa 1.1.3. 脸书Messenger应用上的M 1.1.4. 谷歌语音助手Assistant 1.2. 借由人工智能技术,虚拟助手将…

在ABP的应用程序中引用其它的ABP模块

背景 自从使用了ABP框架,模块越拆越细。 1个模块需要打包解决方案“src”下的12个项目:那么我们就需要自动打包并且推送到私有nuget存储库才行。 自动打包可以用Gitlab和配套的Gitlab Runner来完成,参看我的: Gitlab Runner自动打包C#项目并推送到NuGet仓库 私有nuget存储库…