Définir une horloge analogique sur le temps avec les gestes, le toucher aiguille des minutes dans le sens horaire ou anti-horaire
-
21-12-2019 - |
Question
Je suis coincé à essayer de faire une classe qui permettent aux utilisateurs de définir une horloge analogique sur le temps.Ils ont à se déplacer aiguille des minutes, pas heures à la main, dans le sens horaire ou antihoraire pour régler l'heure actuelle.Aiguille des heures se déplace lui-même en fonction des minutes aiguille des progrès, mais je ne peux pas être en mesure de déplacer l'aiguille des heures correctement.Il n'a pas un mouvement fluide à chaque fois que traverse douze heures et six heures, où il y a de l'angle de points critiques.
C'est ma séance d'entraînement jusqu'à ce moment.À douze heures, l'angle est égal à 0 degrés, l'angle minimal de cours, et à six heures, l'angle est de 180 degrés, le maximum de l'angle.Ainsi, à partir de douze à six (sens horaire), nous avons des angles positifs (0,180), et, à partir de six à douze (sens horaire), nous avons négatif angles (-180,0).C'est ok, mais si je veux calculer quelle sera la position correcte de l'aiguille des heures en fonction avec des minutes aiguille des progrès, j'ai à traduire que les angles de 0-360 degrés de la gamme.
C'est là que je me charge de gestes:
@Override
public boolean onTouch(View v, MotionEvent event) {
// Clock is the clock sphere and the minutes hand.
final float xc = clock.getTranslationX() + (clock.getWidth() / 2);
final float yc = clock.getTranslationY() + (clock.getHeight() / 2);
final float x = event.getX();
final float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
clock.clearAnimation();
mMinutesCurrAngle = Math.toDegrees(Math.atan2(x - xc, yc - y));
break;
case MotionEvent.ACTION_MOVE:
/**
* Translate angles from [-179,179] to [0,360] to be able to move
* hours hand properly.
*/
// Start Angle
mMinutesCurrAngle = set360Angle(mMinutesCurrAngle);
mMinutesPrevAngle = mMinutesCurrAngle;
// Finish angle
mMinutesCurrAngle = Math.toDegrees(Math.atan2(event.getX() - xc, yc - event.getY()));
mMinutesCurrAngle = set360Angle(mMinutesCurrAngle);
if ((mMinutesCurrAngle > mMinutesPrevAngle)) {
// Clockwise between 12 and 6
mHoursCurrAngle = mLastSpinHoursAngle + (mMinutesCurrAngle / 12);
} else if ((mMinutesCurrAngle < mMinutesPrevAngle)) {
// counter-Clockwise between 6 and 12
mHoursCurrAngle = mLastSpinHoursAngle + (mMinutesCurrAngle / 12);
} else if ((mMinutesCurrAngle > mMinutesPrevAngle) && (mMinutesCurrAngle < 0)) {
// Clockwise between 6 and 12
mHoursCurrAngle = mLastSpinHoursAngle + (- mMinutesCurrAngle / 12);
} else if ((mMinutesCurrAngle < mMinutesPrevAngle) && (mMinutesCurrAngle < 0)) {
// counter-Clockwise between 6 and 12
mHoursCurrAngle = mLastSpinHoursAngle + (mMinutesCurrAngle / 12);
}
newSpin();
// Transelate angles to the original format to represent them properly.
mMinutesPrevAngle = translate360Angle(mMinutesPrevAngle);
mMinutesCurrAngle = translate360Angle(mMinutesCurrAngle);
animate(clock, mMinutesPrevAngle, mMinutesCurrAngle, 0);
animate(hour, mHoursPrevAngle, mHoursCurrAngle, 0);
mHoursPrevAngle = mHoursCurrAngle;
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
C'est là que je traduire les angles:
/**
* Translate angles from [-179,179] to [0,360] to be able to move
* hours hand properly.
* @param minutesAngle
* @return
*/
private double set360Angle(double angle) {
if (angle < 0) return (360 + angle);
else return angle;
}
/**
* Transelate angles to the original format to represent them properly.
* @param angle
* @return
*/
private double translate360Angle(double angle) {
if (angle > 180) return (-360 + angle);
else return angle;
}
Et c'est là où je sais que si l'aiguille des minutes commence un nouveau spin:
private void newSpin() {
if (translate360Angle(mMinutesPrevAngle) < 0 && translate360Angle(mMinutesCurrAngle) > 0) {
// New Spin clockwise
// I must remember hour hand angle
mLastSpinHoursAngle = mHoursPrevAngle;
} else if (translate360Angle(mMinutesPrevAngle) > 0 && translate360Angle(mMinutesCurrAngle) < 0) {
// New Spin counter-clockwise
// I must remember hour hand angle
mLastSpinHoursAngle = mHoursPrevAngle;
}
}
Quelqu'un peut-il m'aider un petit peu?si quelqu'un peut m'aider, je vous promets de mettre votre nom pour mon premier enfant à naître fille ...c'est juste une blague.
La solution
J'ai découvert où était le problème...
Le problème était le "si les conditions" à l'intérieur de newSpin() la méthode.Ici, avant de vérifier les conditions, j'ai traduit les angles pour le format de l'original (de 0 à 180 degrés pendant douze heures à six heures, aiguilles d'une montre, et de -180 ° à 0°, pour six heures à douze heures, dans le sens des aiguilles trop).Ainsi, au lieu de vérifier si l'utilisateur démarre une nouvelle spin avec aiguille des minutes, Il a été l'ajout/soustraction d'un nouveau spin à chaque fois que l'utilisateur passe par six heures au lieu de douze heures.
Alors, j'ai fait réparer la modification de ces conditions, et de vérifier à la fois des minutes aiguille des angles, anciennes et actuelles, sur 360 degrés format.Maintenant, si l'angle est plus grand que 355 degrés et l'angle courant est inférieure à 5 degrés, j'ai ajouter une nouvelle rotation à mSpinNumber.De même, si l'angle est inférieur à 5 degrés et l'angle actuel est plus grand que 355 degrés, je soustrais un tour à mSpinNumber.J'ai aussi fait du changement de la méthode nom de newSpin() pour calculateHourHandAngle().
private void calculateHourHandAngle() {
if ((mMinutesPrevAngle > 355) && (mMinutesCurrAngle < 5)) {
// New Spin clockwise
mSpinNumber++;
} else if ((mMinutesPrevAngle < 5) && (mMinutesCurrAngle > 355)) {
// New Spin counter-clockwise
mSpinNumber--;
}
mHoursCurrAngle = (mSpinNumber * (360/12)) + (mMinutesCurrAngle / 12);
}
J'ai également de se débarrasser de code inutile dans onTouch() la méthode:
@Override
public boolean onTouch(View v, MotionEvent event) {
// Clock is the clock sphere and the minutes hand.
final float xc = clock.getTranslationX() + (clock.getWidth() / 2);
final float yc = clock.getTranslationY() + (clock.getHeight() / 2);
final float x = event.getX();
final float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
clock.clearAnimation();
hour.clearAnimation();
mMinutesCurrAngle = Math.toDegrees(Math.atan2(x - xc, yc - y));
break;
case MotionEvent.ACTION_MOVE:
/**
* Translate angles from [-179,179] to [0,360] to be able to move
* hours hand properly.
*/
// Start Angle
mMinutesCurrAngle = set360Angle(mMinutesCurrAngle);
mMinutesPrevAngle = mMinutesCurrAngle;
// Finish angle
mMinutesCurrAngle = Math.toDegrees(Math.atan2(event.getX() - xc, yc - event.getY()));
mMinutesCurrAngle = set360Angle(mMinutesCurrAngle);
calculateHourHandAngle();
animate(clock, translate360Angle(mMinutesPrevAngle), translate360Angle(mMinutesCurrAngle), 0);
animate(hour, mHoursPrevAngle, mHoursCurrAngle, 0);
mHoursPrevAngle = mHoursCurrAngle;
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
Maintenant je être en mesure de savoir à quelle heure avez-définie par l'utilisateur, parce que je sais que la position initiale des mains de l'horloge, le nombre de tours et l'aiguille des minutes d'angle.