美文网首页
一个圆形的CycleView

一个圆形的CycleView

作者: 我有一口小白牙 | 来源:发表于2017-05-23 17:08 被阅读39次

    先贴效果图

    image.png

    图中的小圆点是可以随着手指的滑动, 绕着绿色的圆移动的哦
    这个demo只是实现了部分功能, 但是手指跟随圆移动的逻辑很好玩..
    贴代码:
    public class CycleView extends View {

    private int mMaxProcess = 30;
    
    private int mCurrentProcess = 5;
    
    private static final double RADIAN = 180 / Math.PI;
    
    private Context mContext;
    
    private Paint mBigCyclePaint;
    
    private Paint mMiddleCyclePaint;
    
    private Paint mSmallCyclePaint;
    
    private double mCurrentAngle;
    
    private int mBigCycleradius = 400;
    
    private float mWheelCurX, mWheelCurY;
    
    private CurrentProcessListener mCurrentProcessListener;
    
    public void setmCurrentProcessListener(CurrentProcessListener mCurrentProcessListener) {
        this.mCurrentProcessListener = mCurrentProcessListener;
    }
    
    interface CurrentProcessListener {
        void current(int current);
    }
    
    public CycleView(Context context) {
        this(context, null);
    }
    
    public CycleView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    
    public CycleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }
    
    /**
     * 初始化
     *
     * @param context
     * @param attrs
     */
    private void init(Context context, AttributeSet attrs) {
        this.mContext = context;
        mBigCyclePaint = new Paint();
        mBigCyclePaint.setColor(Color.GREEN);
        mBigCyclePaint.setFlags(Paint.ANTI_ALIAS_FLAG);
        mBigCyclePaint.setStyle(Paint.Style.STROKE);
        mBigCyclePaint.setStrokeWidth(10);
    
        mMiddleCyclePaint = new Paint();
        mMiddleCyclePaint.setColor(Color.BLUE);
        mMiddleCyclePaint.setFlags(Paint.ANTI_ALIAS_FLAG);
        mMiddleCyclePaint.setStyle(Paint.Style.STROKE);
        mMiddleCyclePaint.setStrokeWidth(10);
    
        mSmallCyclePaint = new Paint();
        mSmallCyclePaint.setColor(Color.RED);
        mSmallCyclePaint.setFlags(Paint.ANTI_ALIAS_FLAG);
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int width = getWidth();
        int height = getHeight();
        canvas.drawCircle(width / 2, height / 2, mBigCycleradius, mBigCyclePaint);
    
        canvas.drawCircle(width / 2 + 80, height / 2 + 80, 260, mMiddleCyclePaint);
    
        canvas.drawCircle(mWheelCurX, mWheelCurY, 60, mSmallCyclePaint);
    
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                float cos = computeCos(x, y);
                //1, 算出点击的度数
                if (x < getWidth() / 2) { // 滑动超过180度
                    mCurrentAngle = Math.PI * RADIAN + Math.acos(cos) * RADIAN;
                } else { // 没有超过180度
                    mCurrentAngle = Math.PI * RADIAN - Math.acos(cos) * RADIAN;
                }
                //有了角度,
    
                refershWheelCurPosition(cos);//重装小圆点的位置
                if (mCurrentProcessListener != null) {
                    //把当前的角度改了,
                    //开始的角度, 应该是135°
                    double angle = 0;
                    if (mCurrentAngle < 135) {
                        angle = mCurrentAngle + (360-135);
                    } else {
                        angle = mCurrentAngle - 135;
                    }
                    mCurrentProcess = (int) (angle / 360 * mMaxProcess);
                    mCurrentProcessListener.current(mCurrentProcess);
                }
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
    
                break;
        }
        return true;
    }
    private void refershWheelCurPosition(double cos) {
        mWheelCurX = calcXLocationInWheel(mCurrentAngle, cos);
        mWheelCurY = calcYLocationInWheel(cos);
    }
    
    private float calcXLocationInWheel(double angle, double cos) {
        if (angle < 180) {
            return (float) (getMeasuredWidth() / 2 + Math.sqrt(1 - cos * cos) * mBigCycleradius);
        } else {
            return (float) (getMeasuredWidth() / 2 - Math.sqrt(1 - cos * cos) * mBigCycleradius);
        }
    }
    
    private float calcYLocationInWheel(double cos) {
        return getMeasuredHeight() / 2 + mBigCycleradius * (float) cos;
    }
    
    /**
     * 拿到倾斜的cos值
     */
    private float computeCos(float x, float y) {
        float width = x - getWidth() / 2;
        float height = y - getHeight() / 2;
        float slope = (float) Math.sqrt(width * width + height * height);
        return height / slope;
    }
    

    }

    相关文章

      网友评论

          本文标题:一个圆形的CycleView

          本文链接:https://www.haomeiwen.com/subject/nblgxxtx.html