1、控件有很多属性,如android:id、android:layout_width、android:layout_height等,但是这些属性都是系统自带的属性。使用attrs.xml文件,可以自己定义属性。用attrs.xml文件自己定义了属性。

2、xmlns:test="http://schemas.android.com/apk/res/org.jinkia.jk_rockerview.RockerView"
(其中org.jinkia.jk_rockerview.RockerView是包名)
xmlns:app="http://schemas.android.com/apk/res-auto"

3、首先从R.styleable.RockerView获得了TypedArray变量,
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RockerView);
// 可移动区域背景
Drawable areaBackground = typedArray.getDrawable(R.styleable.RockerView_areaBackground);
属性格式为“RockerView_areaBackground”

layout.xml

 

attrs.xml

<?xml version="1.0" encoding="utf-8"?>                                   

org.jinkia.jk_rockerview.RockerView.java

package org.jinkia.jk_rockerview;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 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/2    private 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) {                // XML                mAreaBitmap = 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) {                // XML                mRockerBitmap = 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();    }    @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) {            // 具体的值和match_parent            measureWidth = widthSize;        } else {            // wrap_content            measureWidth = DEFAULT_SIZE;        }        if (heightMode == MeasureSpec.EXACTLY) {            measureHeight = heightSize;        } else {            measureHeight = DEFAULT_SIZE;        }        setMeasuredDimension(measureWidth, measureHeight);    }    @Override    protected 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);        }    }    @Override    public 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;        // 建立对应 bitmap        Bitmap 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 listenr) {        mOnDistanceLevelListener = listenr;    }    /**     * 摇动方向监听接口     */    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;    }}

更多相关文章

  1. Android在应用中固定屏幕方向
  2. LinearLayout中实现水平方向上的两个textview一个居左,一个居右的
  3. Android AsyncTask完全解析,带你从源码的角度彻底理解
  4. Android学习方向
  5. 通过XML设置屏幕方向(android:screenOrientation)详解
  6. 屏幕方向android:screenOrientation
  7. Android获取手机方向
  8. android-详解Android中的屏幕方向

随机推荐

  1. Android撬动IT市场的新支点
  2. Day1.1-Android简介之发展史、操作系统、
  3. URI是什么,在Android中有什么作用?
  4. Android(安卓)Studio的基本控件 图片框与
  5. Android中自动朗读(TTS)的简单使用
  6. Android 插件化 动态升级
  7. Android(安卓)WebView的加载超时处理
  8. AndroidManifest.xml文件剖析
  9. android Aspectj实践问题
  10. android 一个很漂亮的控件ObservableScro