Vue personnalisée drawArc, détecte le contact de l'utilisateur sur le chemin de dessin de l'arc

Je crée une vue personnalisée qui est une sorte de vue de progression du curseur d'arc. Je peux dessiner plus ou moins de l'arc en fonction de l'endroit où l'utilisateur touche (sur l'axe des x) en calculant le balayage, je le fais en calculant d'abord la perception Où l'utilisateur a touché l'axe x..0% serait tout le chemin vers la gauche et 100% serait tout le chemin vers la droite.

Je voulais aller plus loin, au lieu de dessiner l'arc en fonction de la coordonnée x que l'utilisateur appuie, je veux que cela se déplace uniquement lorsque l'utilisateur touche le chemin de traction d'arc réel, donc c'est plus réaliste. Je suis encore nouveau sur les vues personnalisées et mes mathématiques sont limitées mais si je reçois quelques conseils, je vous en serions reconnaissant.

  • Android: reprendre l'application du poste précédent
  • Surlignez sur clickbespan cliquez sur
  • Chronographe TextView Android
  • MPAndroidChart - Premières et dernières barres ne rendant pas correctement
  • Capture RatingBar Click
  • Pourquoi l'apk non aligné est-il nécessaire?
  • Comment il ressemble quand l'utilisateur se déplace là-dedans sur la zone du rectangle en pourcentage le long de l'axe des x

    class ArcProgress extends View { Context cx; float width; float height; float center_x, center_y; final RectF oval = new RectF(); final RectF touchArea = new RectF(); float sweep = 0; float left, right; int percent = 0; public ArcProgress(Context context) { super(context); cx = context; } public int getPercentage() { return percent; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); setBackgroundColor(0xfff0ebde); width = (float) getWidth(); height = (float) getHeight(); float radius; if (width > height) { radius = height / 3; } else { radius = width / 3; } Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(0xffd2c8b6); paint.setStrokeWidth(35); paint.setStyle(Paint.Style.STROKE); center_x = width / 2; center_y = height / 2; left = center_x - radius; float top = center_y - radius; right = center_x + radius; float bottom = center_y + radius; oval.set(left, top, right, bottom); //this is the background arc, it remains constant canvas.drawArc(oval, 180, 180, false, paint); paint.setStrokeWidth(10); paint.setColor(0xffe0524d); //this is the red arc whichhas its sweep argument manipulated by on touch canvas.drawArc(oval, 180, sweep, false, paint); } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_MOVE) { float xPosition = event.getX(); float yPosition = event.getY(); if (oval.contains(xPosition, yPosition)) { float x = xPosition - left; float s = x * 100; float b = s / oval.width(); percent = Math.round(b); sweep = (180 / 100.0f) * (float) percent; invalidate(); } else { if (xPosition < left) { percent = 0; sweep = (180 / 100.0f) * (float) percent; invalidate(); } if (xPosition > right) { percent = 100; sweep = (180 / 100.0f) * (float) percent; invalidate(); } } } return true; } } 

    2 Solutions collect form web for “Vue personnalisée drawArc, détecte le contact de l'utilisateur sur le chemin de dessin de l'arc”

    Est-ce que ça marche pour toi? Vous n'avez pas besoin de beaucoup de maths. Vous pouvez calculer la distance du point tactile du centre de votre arc (c'est un cercle, donc c'est facile) et comparez-le avec le rayon que vous utilisez. Cela vous dira si le point est sur l'arc (presque, voir ci-dessous pour le cas complet).

     Point touchEv = ...; Point circleCenter = ...; //the radius of the circle you used to draw the arc float circleRadius = ...; //how far from the arc should a touch point treated as it's on the arc float maxDiff = getResources().getDimension(R.dimen.max_diff_dp); //calculate the distance of the touch point from the center of your circle float dist = Math.pow(touchEv.x-circleCenter.x,2) + Math.pow(touchEv.y- circleCenter.y,2) dist = Math.sqrt(dist); //We also need the bounding rect of the top half of the circle (the visible arc) Rect topBoundingRect = new Rect(circleCenter.x - circleRadius, circleCenter.y - circleRadius, circleCenter.x + circleRadius, circleCenter.y); if (Math.abs(dist - circleRadius) <= maxDiff && topBoundingRect.contains(touchEv.x, touchEv.y)) { // the user is touching the arc } 

    Je veux que cela se déplace uniquement lorsque l'utilisateur touche le chemin d'attraction réel

    Au début de onTouchEvent() vous devez vérifier si xPosition et yPosition remplissent certaines conditions. Si oui, vous faites les choses, ce que vous faites maintenant. Si non, return true .

    Condition:

    Nous voulons vérifier si x, y sont dans cet arrière-plan arc gris:

    Entrez la description de l'image ici

    Calculons une distance de (x, y) à ce point (a, b) au centre:

     final dist = distance(x, y, a, b) 

    distance() est une distance euclidienne simple entre les points (x, y) et (a, b):

     double distance(int x, int y, int a, int b) { return Math.sqrt((x - a) * (x - a) + (y - b) * (y - b)); } 

    X, y sont dans cet arrière-plan d'arc gris, si y > Y && dist >= r && dist <= R

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.