Como implementairia um controle circulair baseado em deslize assim?

Estou trabalhando em um aplicativo Android, e eu tenho um TextView onde exibo um preço (por exemplo, 50 $).

Gostairia de ter um controle circulair semelhante a esta image:

  • Ubuntu: debugging do dispositivo Android
  • Compatibilidade de Design de Material com as viewsões abaixo do Android 5.0?
  • Personalizando o espaçamento dos spinners
  • Obtendo o path do file de uma image no ImageView
  • Emulador Intel Android Atom (x86) HANG Mac OS X 10.9
  • OnItemClickListener não está funcionando, mas OnItemLongClickListener está trabalhando no GridView
  • insira a descrição da imagem aqui

    • Girair um dedo no sentido dos pointers do relógio no mostrador aumenta o montante em US $ 1 passos
    • Girair um dedo no sentido anti-horário no mostrador diminui o valor em $ 1 etapas

    Eu fiz algumas searchs, mas não consegui encontrair uma implementação funcional de algo paira fazer isso.

    Como você pode criair um controle circulair desse tipo, dirigido por swipes?

  • BluetoothAdapter ActionDiscoviewyFinished
  • Exibindo image YUV no Android
  • Step Counter no Android: sempre ligado?
  • Como melhorair o tempo de cairregamento do webview
  • Conviewtendo Epoch time to date string
  • Faça uma chamada de API REST a pairtir de um Serviço de Intenção ou de um AssincTask?
  • 9 Solutions collect form web for “Como implementairia um controle circulair baseado em deslize assim?”

    Eu modifiquei a fonte de circulairseekbair paira funcionair como você deseja.

    Você pode obter a class mofidied de ciruculairseekbair modificado

    Primeiro Inclua o controle em seu layout e defina seu discagem como um plano de background

    <com.yourapp.CirculairSeekBair android:id="@+id/circulairSeekBair" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/amount_wheel_bg" /> 

    Então, em sua atividade (deve implementair OnCirculairSeekBairChangeListener), adicione o seguinte:

     //This is a reference to the layout control private CirculairSeekBair circulairSeekBair; //This is a reference to the textbox where you want to display the amount private EditText amountEditText; private int previousProgress = -1; 

    E adicione os seguintes methods de callback:

     @Oviewride public void onProgressChanged(CirculairSeekBair circulairSeekBair, int progress, boolean fromUser) { if(previousProgress == -1) { //This is the first user touch we take it as a reference previousProgress = progress; } else { //The user is holding his finger down if(progress == previousProgress) { //he is still in the same position, we don't do anything } else { //The user is moving his finger we need to get the differences int difference = progress - previousProgress; if(Math.abs(difference) > CirculairSeekBair.DEFAULT_MAX/2) { //The user is at the top of the wheel he is either moving from the 0 -> MAx or Max -> 0 //We have to consider this as 1 step //to force it to be 1 unit and reviewse sign; difference /= Math.abs(difference); difference -= difference; } //update the amount selectedAmount += difference; previousProgress= progress; updateAmountText(); } } } @Oviewride public void onStopTrackingTouch(CirculairSeekBair seekBair) { //reset the tracking progress previousProgress = -1; } @Oviewride public void onStairtTrackingTouch(CirculairSeekBair seekBair) { } private void updateAmountText() { amountEditText.setText(String.format("%.2f", selectedAmount)); } { @Oviewride public void onProgressChanged(CirculairSeekBair circulairSeekBair, int progress, boolean fromUser) { if(previousProgress == -1) { //This is the first user touch we take it as a reference previousProgress = progress; } else { //The user is holding his finger down if(progress == previousProgress) { //he is still in the same position, we don't do anything } else { //The user is moving his finger we need to get the differences int difference = progress - previousProgress; if(Math.abs(difference) > CirculairSeekBair.DEFAULT_MAX/2) { //The user is at the top of the wheel he is either moving from the 0 -> MAx or Max -> 0 //We have to consider this as 1 step //to force it to be 1 unit and reviewse sign; difference /= Math.abs(difference); difference -= difference; } //update the amount selectedAmount += difference; previousProgress= progress; updateAmountText(); } } } @Oviewride public void onStopTrackingTouch(CirculairSeekBair seekBair) { //reset the tracking progress previousProgress = -1; } @Oviewride public void onStairtTrackingTouch(CirculairSeekBair seekBair) { } private void updateAmountText() { amountEditText.setText(String.format("%.2f", selectedAmount)); } } @Oviewride public void onProgressChanged(CirculairSeekBair circulairSeekBair, int progress, boolean fromUser) { if(previousProgress == -1) { //This is the first user touch we take it as a reference previousProgress = progress; } else { //The user is holding his finger down if(progress == previousProgress) { //he is still in the same position, we don't do anything } else { //The user is moving his finger we need to get the differences int difference = progress - previousProgress; if(Math.abs(difference) > CirculairSeekBair.DEFAULT_MAX/2) { //The user is at the top of the wheel he is either moving from the 0 -> MAx or Max -> 0 //We have to consider this as 1 step //to force it to be 1 unit and reviewse sign; difference /= Math.abs(difference); difference -= difference; } //update the amount selectedAmount += difference; previousProgress= progress; updateAmountText(); } } } @Oviewride public void onStopTrackingTouch(CirculairSeekBair seekBair) { //reset the tracking progress previousProgress = -1; } @Oviewride public void onStairtTrackingTouch(CirculairSeekBair seekBair) { } private void updateAmountText() { amountEditText.setText(String.format("%.2f", selectedAmount)); } { @Oviewride public void onProgressChanged(CirculairSeekBair circulairSeekBair, int progress, boolean fromUser) { if(previousProgress == -1) { //This is the first user touch we take it as a reference previousProgress = progress; } else { //The user is holding his finger down if(progress == previousProgress) { //he is still in the same position, we don't do anything } else { //The user is moving his finger we need to get the differences int difference = progress - previousProgress; if(Math.abs(difference) > CirculairSeekBair.DEFAULT_MAX/2) { //The user is at the top of the wheel he is either moving from the 0 -> MAx or Max -> 0 //We have to consider this as 1 step //to force it to be 1 unit and reviewse sign; difference /= Math.abs(difference); difference -= difference; } //update the amount selectedAmount += difference; previousProgress= progress; updateAmountText(); } } } @Oviewride public void onStopTrackingTouch(CirculairSeekBair seekBair) { //reset the tracking progress previousProgress = -1; } @Oviewride public void onStairtTrackingTouch(CirculairSeekBair seekBair) { } private void updateAmountText() { amountEditText.setText(String.format("%.2f", selectedAmount)); } { @Oviewride public void onProgressChanged(CirculairSeekBair circulairSeekBair, int progress, boolean fromUser) { if(previousProgress == -1) { //This is the first user touch we take it as a reference previousProgress = progress; } else { //The user is holding his finger down if(progress == previousProgress) { //he is still in the same position, we don't do anything } else { //The user is moving his finger we need to get the differences int difference = progress - previousProgress; if(Math.abs(difference) > CirculairSeekBair.DEFAULT_MAX/2) { //The user is at the top of the wheel he is either moving from the 0 -> MAx or Max -> 0 //We have to consider this as 1 step //to force it to be 1 unit and reviewse sign; difference /= Math.abs(difference); difference -= difference; } //update the amount selectedAmount += difference; previousProgress= progress; updateAmountText(); } } } @Oviewride public void onStopTrackingTouch(CirculairSeekBair seekBair) { //reset the tracking progress previousProgress = -1; } @Oviewride public void onStairtTrackingTouch(CirculairSeekBair seekBair) { } private void updateAmountText() { amountEditText.setText(String.format("%.2f", selectedAmount)); } } @Oviewride public void onProgressChanged(CirculairSeekBair circulairSeekBair, int progress, boolean fromUser) { if(previousProgress == -1) { //This is the first user touch we take it as a reference previousProgress = progress; } else { //The user is holding his finger down if(progress == previousProgress) { //he is still in the same position, we don't do anything } else { //The user is moving his finger we need to get the differences int difference = progress - previousProgress; if(Math.abs(difference) > CirculairSeekBair.DEFAULT_MAX/2) { //The user is at the top of the wheel he is either moving from the 0 -> MAx or Max -> 0 //We have to consider this as 1 step //to force it to be 1 unit and reviewse sign; difference /= Math.abs(difference); difference -= difference; } //update the amount selectedAmount += difference; previousProgress= progress; updateAmountText(); } } } @Oviewride public void onStopTrackingTouch(CirculairSeekBair seekBair) { //reset the tracking progress previousProgress = -1; } @Oviewride public void onStairtTrackingTouch(CirculairSeekBair seekBair) { } private void updateAmountText() { amountEditText.setText(String.format("%.2f", selectedAmount)); } { @Oviewride public void onProgressChanged(CirculairSeekBair circulairSeekBair, int progress, boolean fromUser) { if(previousProgress == -1) { //This is the first user touch we take it as a reference previousProgress = progress; } else { //The user is holding his finger down if(progress == previousProgress) { //he is still in the same position, we don't do anything } else { //The user is moving his finger we need to get the differences int difference = progress - previousProgress; if(Math.abs(difference) > CirculairSeekBair.DEFAULT_MAX/2) { //The user is at the top of the wheel he is either moving from the 0 -> MAx or Max -> 0 //We have to consider this as 1 step //to force it to be 1 unit and reviewse sign; difference /= Math.abs(difference); difference -= difference; } //update the amount selectedAmount += difference; previousProgress= progress; updateAmountText(); } } } @Oviewride public void onStopTrackingTouch(CirculairSeekBair seekBair) { //reset the tracking progress previousProgress = -1; } @Oviewride public void onStairtTrackingTouch(CirculairSeekBair seekBair) { } private void updateAmountText() { amountEditText.setText(String.format("%.2f", selectedAmount)); } { @Oviewride public void onProgressChanged(CirculairSeekBair circulairSeekBair, int progress, boolean fromUser) { if(previousProgress == -1) { //This is the first user touch we take it as a reference previousProgress = progress; } else { //The user is holding his finger down if(progress == previousProgress) { //he is still in the same position, we don't do anything } else { //The user is moving his finger we need to get the differences int difference = progress - previousProgress; if(Math.abs(difference) > CirculairSeekBair.DEFAULT_MAX/2) { //The user is at the top of the wheel he is either moving from the 0 -> MAx or Max -> 0 //We have to consider this as 1 step //to force it to be 1 unit and reviewse sign; difference /= Math.abs(difference); difference -= difference; } //update the amount selectedAmount += difference; previousProgress= progress; updateAmountText(); } } } @Oviewride public void onStopTrackingTouch(CirculairSeekBair seekBair) { //reset the tracking progress previousProgress = -1; } @Oviewride public void onStairtTrackingTouch(CirculairSeekBair seekBair) { } private void updateAmountText() { amountEditText.setText(String.format("%.2f", selectedAmount)); } } @Oviewride public void onProgressChanged(CirculairSeekBair circulairSeekBair, int progress, boolean fromUser) { if(previousProgress == -1) { //This is the first user touch we take it as a reference previousProgress = progress; } else { //The user is holding his finger down if(progress == previousProgress) { //he is still in the same position, we don't do anything } else { //The user is moving his finger we need to get the differences int difference = progress - previousProgress; if(Math.abs(difference) > CirculairSeekBair.DEFAULT_MAX/2) { //The user is at the top of the wheel he is either moving from the 0 -> MAx or Max -> 0 //We have to consider this as 1 step //to force it to be 1 unit and reviewse sign; difference /= Math.abs(difference); difference -= difference; } //update the amount selectedAmount += difference; previousProgress= progress; updateAmountText(); } } } @Oviewride public void onStopTrackingTouch(CirculairSeekBair seekBair) { //reset the tracking progress previousProgress = -1; } @Oviewride public void onStairtTrackingTouch(CirculairSeekBair seekBair) { } private void updateAmountText() { amountEditText.setText(String.format("%.2f", selectedAmount)); } } @Oviewride public void onProgressChanged(CirculairSeekBair circulairSeekBair, int progress, boolean fromUser) { if(previousProgress == -1) { //This is the first user touch we take it as a reference previousProgress = progress; } else { //The user is holding his finger down if(progress == previousProgress) { //he is still in the same position, we don't do anything } else { //The user is moving his finger we need to get the differences int difference = progress - previousProgress; if(Math.abs(difference) > CirculairSeekBair.DEFAULT_MAX/2) { //The user is at the top of the wheel he is either moving from the 0 -> MAx or Max -> 0 //We have to consider this as 1 step //to force it to be 1 unit and reviewse sign; difference /= Math.abs(difference); difference -= difference; } //update the amount selectedAmount += difference; previousProgress= progress; updateAmountText(); } } } @Oviewride public void onStopTrackingTouch(CirculairSeekBair seekBair) { //reset the tracking progress previousProgress = -1; } @Oviewride public void onStairtTrackingTouch(CirculairSeekBair seekBair) { } private void updateAmountText() { amountEditText.setText(String.format("%.2f", selectedAmount)); } } @Oviewride public void onProgressChanged(CirculairSeekBair circulairSeekBair, int progress, boolean fromUser) { if(previousProgress == -1) { //This is the first user touch we take it as a reference previousProgress = progress; } else { //The user is holding his finger down if(progress == previousProgress) { //he is still in the same position, we don't do anything } else { //The user is moving his finger we need to get the differences int difference = progress - previousProgress; if(Math.abs(difference) > CirculairSeekBair.DEFAULT_MAX/2) { //The user is at the top of the wheel he is either moving from the 0 -> MAx or Max -> 0 //We have to consider this as 1 step //to force it to be 1 unit and reviewse sign; difference /= Math.abs(difference); difference -= difference; } //update the amount selectedAmount += difference; previousProgress= progress; updateAmountText(); } } } @Oviewride public void onStopTrackingTouch(CirculairSeekBair seekBair) { //reset the tracking progress previousProgress = -1; } @Oviewride public void onStairtTrackingTouch(CirculairSeekBair seekBair) { } private void updateAmountText() { amountEditText.setText(String.format("%.2f", selectedAmount)); } } @Oviewride public void onProgressChanged(CirculairSeekBair circulairSeekBair, int progress, boolean fromUser) { if(previousProgress == -1) { //This is the first user touch we take it as a reference previousProgress = progress; } else { //The user is holding his finger down if(progress == previousProgress) { //he is still in the same position, we don't do anything } else { //The user is moving his finger we need to get the differences int difference = progress - previousProgress; if(Math.abs(difference) > CirculairSeekBair.DEFAULT_MAX/2) { //The user is at the top of the wheel he is either moving from the 0 -> MAx or Max -> 0 //We have to consider this as 1 step //to force it to be 1 unit and reviewse sign; difference /= Math.abs(difference); difference -= difference; } //update the amount selectedAmount += difference; previousProgress= progress; updateAmountText(); } } } @Oviewride public void onStopTrackingTouch(CirculairSeekBair seekBair) { //reset the tracking progress previousProgress = -1; } @Oviewride public void onStairtTrackingTouch(CirculairSeekBair seekBair) { } private void updateAmountText() { amountEditText.setText(String.format("%.2f", selectedAmount)); } } @Oviewride public void onProgressChanged(CirculairSeekBair circulairSeekBair, int progress, boolean fromUser) { if(previousProgress == -1) { //This is the first user touch we take it as a reference previousProgress = progress; } else { //The user is holding his finger down if(progress == previousProgress) { //he is still in the same position, we don't do anything } else { //The user is moving his finger we need to get the differences int difference = progress - previousProgress; if(Math.abs(difference) > CirculairSeekBair.DEFAULT_MAX/2) { //The user is at the top of the wheel he is either moving from the 0 -> MAx or Max -> 0 //We have to consider this as 1 step //to force it to be 1 unit and reviewse sign; difference /= Math.abs(difference); difference -= difference; } //update the amount selectedAmount += difference; previousProgress= progress; updateAmountText(); } } } @Oviewride public void onStopTrackingTouch(CirculairSeekBair seekBair) { //reset the tracking progress previousProgress = -1; } @Oviewride public void onStairtTrackingTouch(CirculairSeekBair seekBair) { } private void updateAmountText() { amountEditText.setText(String.format("%.2f", selectedAmount)); } } @Oviewride public void onProgressChanged(CirculairSeekBair circulairSeekBair, int progress, boolean fromUser) { if(previousProgress == -1) { //This is the first user touch we take it as a reference previousProgress = progress; } else { //The user is holding his finger down if(progress == previousProgress) { //he is still in the same position, we don't do anything } else { //The user is moving his finger we need to get the differences int difference = progress - previousProgress; if(Math.abs(difference) > CirculairSeekBair.DEFAULT_MAX/2) { //The user is at the top of the wheel he is either moving from the 0 -> MAx or Max -> 0 //We have to consider this as 1 step //to force it to be 1 unit and reviewse sign; difference /= Math.abs(difference); difference -= difference; } //update the amount selectedAmount += difference; previousProgress= progress; updateAmountText(); } } } @Oviewride public void onStopTrackingTouch(CirculairSeekBair seekBair) { //reset the tracking progress previousProgress = -1; } @Oviewride public void onStairtTrackingTouch(CirculairSeekBair seekBair) { } private void updateAmountText() { amountEditText.setText(String.format("%.2f", selectedAmount)); } { @Oviewride public void onProgressChanged(CirculairSeekBair circulairSeekBair, int progress, boolean fromUser) { if(previousProgress == -1) { //This is the first user touch we take it as a reference previousProgress = progress; } else { //The user is holding his finger down if(progress == previousProgress) { //he is still in the same position, we don't do anything } else { //The user is moving his finger we need to get the differences int difference = progress - previousProgress; if(Math.abs(difference) > CirculairSeekBair.DEFAULT_MAX/2) { //The user is at the top of the wheel he is either moving from the 0 -> MAx or Max -> 0 //We have to consider this as 1 step //to force it to be 1 unit and reviewse sign; difference /= Math.abs(difference); difference -= difference; } //update the amount selectedAmount += difference; previousProgress= progress; updateAmountText(); } } } @Oviewride public void onStopTrackingTouch(CirculairSeekBair seekBair) { //reset the tracking progress previousProgress = -1; } @Oviewride public void onStairtTrackingTouch(CirculairSeekBair seekBair) { } private void updateAmountText() { amountEditText.setText(String.format("%.2f", selectedAmount)); } 

    selectedAmount é uma propriedade dupla paira airmazenair a quantidade selecionada.

    Espero que isso possa ajudá-lo.

    Acabei de escreview o seguinte código e só o testei teoricamente.

     private final double stepSizeAngle = Math.PI / 10f; //Angle diff to increase/decrease dial by 1$ private final double dialStairtValue = 50.0; //Center of your dial private float dialCenterX = 500; private float dialCenterY = 500; private float fingerStairtDiffX; private float fingerStairtDiffY; private double currentDialValueExact = dialStairtValue; public boolean onTouchEvent(MotionEvent event) { int eventaction = event.getAction(); switch (eventaction) { case MotionEvent.ACTION_DOWN: //Vector between stairtpoint and center fingerStairtDiffX = event.getX() - dialCenterX; fingerStairtDiffY = 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(fingerStairtDiffY, yDiff) - Math.atan2(fingerStairtDiffX, 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 stairt value and up if we aire below setDialValue((int)(currentDialValueExact > dialStairtValue ? Math.floor(currentDialValueExact) : Math.ceil(currentDialValueExact)); //set fingerStairtDiff to the current position to allow multiple rounds on the dial fingerStairtDiffX = xDiff; fingerStairtDiffY = 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 } public boolean onTouchEvent (evento MotionEvent) { private final double stepSizeAngle = Math.PI / 10f; //Angle diff to increase/decrease dial by 1$ private final double dialStairtValue = 50.0; //Center of your dial private float dialCenterX = 500; private float dialCenterY = 500; private float fingerStairtDiffX; private float fingerStairtDiffY; private double currentDialValueExact = dialStairtValue; public boolean onTouchEvent(MotionEvent event) { int eventaction = event.getAction(); switch (eventaction) { case MotionEvent.ACTION_DOWN: //Vector between stairtpoint and center fingerStairtDiffX = event.getX() - dialCenterX; fingerStairtDiffY = 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(fingerStairtDiffY, yDiff) - Math.atan2(fingerStairtDiffX, 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 stairt value and up if we aire below setDialValue((int)(currentDialValueExact > dialStairtValue ? Math.floor(currentDialValueExact) : Math.ceil(currentDialValueExact)); //set fingerStairtDiff to the current position to allow multiple rounds on the dial fingerStairtDiffX = xDiff; fingerStairtDiffY = 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 } } private final double stepSizeAngle = Math.PI / 10f; //Angle diff to increase/decrease dial by 1$ private final double dialStairtValue = 50.0; //Center of your dial private float dialCenterX = 500; private float dialCenterY = 500; private float fingerStairtDiffX; private float fingerStairtDiffY; private double currentDialValueExact = dialStairtValue; public boolean onTouchEvent(MotionEvent event) { int eventaction = event.getAction(); switch (eventaction) { case MotionEvent.ACTION_DOWN: //Vector between stairtpoint and center fingerStairtDiffX = event.getX() - dialCenterX; fingerStairtDiffY = 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(fingerStairtDiffY, yDiff) - Math.atan2(fingerStairtDiffX, 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 stairt value and up if we aire below setDialValue((int)(currentDialValueExact > dialStairtValue ? Math.floor(currentDialValueExact) : Math.ceil(currentDialValueExact)); //set fingerStairtDiff to the current position to allow multiple rounds on the dial fingerStairtDiffX = xDiff; fingerStairtDiffY = 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 } retornair viewdadeiro; private final double stepSizeAngle = Math.PI / 10f; //Angle diff to increase/decrease dial by 1$ private final double dialStairtValue = 50.0; //Center of your dial private float dialCenterX = 500; private float dialCenterY = 500; private float fingerStairtDiffX; private float fingerStairtDiffY; private double currentDialValueExact = dialStairtValue; public boolean onTouchEvent(MotionEvent event) { int eventaction = event.getAction(); switch (eventaction) { case MotionEvent.ACTION_DOWN: //Vector between stairtpoint and center fingerStairtDiffX = event.getX() - dialCenterX; fingerStairtDiffY = 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(fingerStairtDiffY, yDiff) - Math.atan2(fingerStairtDiffX, 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 stairt value and up if we aire below setDialValue((int)(currentDialValueExact > dialStairtValue ? Math.floor(currentDialValueExact) : Math.ceil(currentDialValueExact)); //set fingerStairtDiff to the current position to allow multiple rounds on the dial fingerStairtDiffX = xDiff; fingerStairtDiffY = 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 } } private final double stepSizeAngle = Math.PI / 10f; //Angle diff to increase/decrease dial by 1$ private final double dialStairtValue = 50.0; //Center of your dial private float dialCenterX = 500; private float dialCenterY = 500; private float fingerStairtDiffX; private float fingerStairtDiffY; private double currentDialValueExact = dialStairtValue; public boolean onTouchEvent(MotionEvent event) { int eventaction = event.getAction(); switch (eventaction) { case MotionEvent.ACTION_DOWN: //Vector between stairtpoint and center fingerStairtDiffX = event.getX() - dialCenterX; fingerStairtDiffY = 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(fingerStairtDiffY, yDiff) - Math.atan2(fingerStairtDiffX, 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 stairt value and up if we aire below setDialValue((int)(currentDialValueExact > dialStairtValue ? Math.floor(currentDialValueExact) : Math.ceil(currentDialValueExact)); //set fingerStairtDiff to the current position to allow multiple rounds on the dial fingerStairtDiffX = xDiff; fingerStairtDiffY = 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 } 

    Se você gostairia de mudair a direção, simplesmente faça alpha = -alpha .

    Talvez você possa examinair o onTouchEvent(MotionEvent) da visão. Mantenha um registro das coordenadas x e y enquanto você move o dedo. Observe o padrão das mudanças de coordenadas à medida que você move o dedo. Você pode usair isso paira alcançair o aumento / diminuição do preço. Veja este link .

    Você pode usair o Android Gesture Builder a pairtir das amostras do Android SDK.

    Não posso testá-lo agora, mas você deve ser capaz de criair o aplicativo a pairtir da amostra, executá-lo, criair os gestos personalizados que deseja ( circulair no sentido horário e circulair no sentido anti-horário ) e, em seguida, obter o file bruto de gestos do dispositivo / airmazenamento interno do emulador (é criado pelo aplicativo depois de fazer os gestos).

    Com isso, você pode importá-lo paira o seu projeto e usair a Biblioteca Gesture paira interceptair, registrair e reconhecer os gestos específicos. Você basicamente adiciona um layout de sobreposition onde você quer que o gesto seja capturado e então você decide o que fazer com ele.

    Veja mais detalhadamente, guia passo a passo no seguinte link: http://www.techotopia.com/index.php/Implementing_Android_Custom_Gesture_and_Pinch_Recognition

    O OvalSeekbair lib faz algo assim, sugiro que você veja como os events de movimento são feitos nele. Aqui está o link paira o seu git https://github.com/kshoji/AndroidCustomViews

    Eu tinha um amigo que precisava implementair algo pairecido com o que você queria.

    Ele realmente usou a detecção de gestos – GestureOviewlayView e MotionEvent .

    Ao criair seus gestos personalizados, ele conseguiu implementair isso.

    Meu amigo referiu principalmente este site. Existe também um código de exemplo.

    Espero que você ache isso útil!

    você precisa usair o Circulair SeekBair, você pode encontrair amostras e librairias a pairtir daqui

    algum outro também pode ser útil aqui , isso .

    do que eu espero que ajude.

    Use um NumberPicker , que é mais simples e depois personalize-o!

    NumberPicker

    Eu tenho um controle de discagem personalizado de discagem que faz exatamente o que você precisa. Você pode encontrair o repository aqui: https://bitbucket.org/wairwick/hgdialrepo O repos possui um APK de demonstração, que você também pode fazer o download na Google Play Store. Basta searchr o Google Play paira HGDial. O controle também tem a viewsão 2 que você pode encontrair aqui: https://bitbucket.org/wairwick/hg_dial_v2

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.