How would I implement a swipe-based circular control like this?

前端 未结 10 2043
北恋
北恋 2021-01-30 23:52

I am working on an Android application, and I have a TextView where I display a price (for example 50$).

I would like to have a circular control similar to this picture:

10条回答
  •  醉酒成梦
    2021-01-31 00:13

    I've just written the following code and only tested it theoretically.

    private final double stepSizeAngle = Math.PI / 10f; //Angle diff to increase/decrease dial by 1$
    private final double dialStartValue = 50.0;
    
    //Center of your dial
    private float dialCenterX = 500;
    private float dialCenterY = 500;
    
    private float fingerStartDiffX;
    private float fingerStartDiffY;
    
    private double currentDialValueExact = dialStartValue;
    
    
    public boolean onTouchEvent(MotionEvent event) {
        int eventaction = event.getAction();
    
        switch (eventaction) {
            case MotionEvent.ACTION_DOWN: 
                //Vector between startpoint and center
                fingerStartDiffX = event.getX() - dialCenterX;
                fingerStartDiffY = event.getY() - dialCenterY;
                break;
    
            case MotionEvent.ACTION_MOVE:
                //Vector between current point and center
                float xDiff = event.getX() - dialCenterX;
                float yDiff = event.getY() - dialCenterY;
    
                //Range from -PI to +PI
                double alpha = Math.atan2(fingerStartDiffY, yDiff) - Math.atan2(fingerStartDiffX, xDiff);
    
                //calculate exact difference between last move and current move.
                //This will take positive and negative direction into account.
                double dialIncrease = alpha / stepSizeAngle;        
                currentDialValueExact += dialIncrease;
    
                //Round down if we're above the start value and up if we are below
                setDialValue((int)(currentDialValueExact > dialStartValue ? Math.floor(currentDialValueExact) : Math.ceil(currentDialValueExact));
    
                //set fingerStartDiff to the current position to allow multiple rounds on the dial
                fingerStartDiffX = xDiff;
                fingerStartDiffY = yDiff;
                break;
        }
    
        // tell the system that we handled the event and no further processing is required
        return true; 
    }
    
    private void setDialValue(int value) {
        //assign value
    }
    

    If you would like to change the direction, simply do alpha = -alpha.

提交回复
热议问题