Vista personalizada drawArc, detecta el tacto del usuario en la trayectoria de trazado del arco

Estoy creando una vista personalizada que es una especie de vista de progreso de arco deslizante. Puedo dibujar más o menos del arco basado en donde el usuario toca (en el eje x) calculando el barrido, lo hago calculando primero el percept Donde el usuario tocó a lo largo del eje x..0% sería todo el camino a la izquierda y el 100% sería todo el camino a la derecha.

Quiero llevar esto un paso más allá, en lugar de dibujar el arco basado en la coordenada x que el usuario presiona, quiero hacer que se mueva sólo cuando el usuario toca el camino de trazado de arco real, por lo que es más realista. Todavía soy nuevo a las vistas de encargo y mi matemáticas es limitado pero si consigo algunos extremidades agradecería agradecido

Cómo se ve cuando el usuario se mueve allí dedo sobre el área del rectángulo como un porcentaje a lo largo del eje 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 “Vista personalizada drawArc, detecta el tacto del usuario en la trayectoria de trazado del arco”

¿Esto funciona para tí? No necesitas un montón de matemáticas. Puede calcular la distancia del punto de contacto desde el centro de su arco (es un círculo por lo que es fácil) y compararlo con el radio que está utilizando. Eso le dirá si el punto está en el arco (casi, ver abajo para el caso completo).

 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 } 

Quiero hacer que se mueva sólo cuando el usuario toca la trayectoria de trazado de arco real

Al principio de onTouchEvent() debe comprobar si xPosition y yPosition cumplen alguna condición. Si es así, usted hace las cosas, que está haciendo ahora. Si no, return true .

Condición:

Queremos comprobar si x, y están en ese fondo de arco gris:

Introduzca aquí la descripción de la imagen

Calculemos una distancia de (x, y) a ese punto (a, b) en el centro:

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

distance() es una distancia euclídea simple entre los puntos (x, y) y (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 están en ese fondo de arco gris, si y > Y && dist >= r && dist <= R

  • ListView desplazamiento de fondo con datos
  • El mapa de bits de Android se ajusta a la cuadrícula
  • Evitar Android volver a agregar automáticamente mi fragmento en el cambio de orientación
  • Pasar referencias a la intención de la actividad
  • ¿Qué es una región no válida en Android?
  • No se puede limpiar el proyecto en Android Studio
  • Android: WebView cargar imagen / contenido en el centro
  • Usar JavaCV y Realm juntos causa "java.lang.UnsatisfiedLinkError"
  • Establecer fecha mínima para DatePickerDialog obtener IllegalArgumentException Fromdate no precede toDate
  • Establecer la fecha / hora de Android mediante programación
  • Cómo analizar una cadena de cookies
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.