¿Cómo dibujo una flecha (en Android)?

Soy bastante nuevo en Android y he estado jugando con Canvas. Estoy tratando de dibujar una flecha, pero sólo tengo suerte con el dibujo del eje, ninguna de las puntas de flecha está funcionando.

He buscado un poco y encontrado un ejemplo de Java, pero Android no tiene GeneralPath o AffineTransform .

Ahora mi código se parece a lo siguiente (la punta de flecha no se parece a una punta de flecha):

 public class DrawableView extends View { Context mContext; private int centerX; private int centerY; private int radius; private double arrLength; private double arrHeading; private int margin = 10; public DrawableView(Context context) { super(context); mContext = context; } @Override protected void onDraw(Canvas canvas) { //Paint Background Paint background = new Paint(); background.setColor(getResources().getColor(R.color.background); canvas.drawRect(0, 0, getWidth(), getHeight(), background); //Set vars for Arrow Paint Paint paint = new Paint(); paint.setColor(getResources().getColor(R.color.arrowColor); centerX = getWidth() / 2; centerY = getHeight() / 2; arrLength = radius - 10; if(centerX < centerY) radius = centerX - margin; else radius = centerY - margin; //Draw Shaft int[] xy = findArrowPos(arrLength, arrHeading); canvas.drawLine(centerX, centerY, xy[0], xy[1], paint); //Draw ArrowHead //This is where I'm confused } private int[] findArrowPos(double length, double angle) { int[] points = new int[2]; double theta = Math.toRadians(angle); points[0] = centerX + (int) (length * Math.cos(theta)); points[1] = centerY + (int) (length * Math.sin(theta)); return points; } } 

He echado un vistazo a los siguientes hilos de orientación:
* Http://www.java-forums.org/awt-swing/6241-how-u-rotate-arrow-mark-line-moves-accordingly.html
* ¿Cómo dibujar una línea de flecha dirigida en Java?

¿Qué hay de usar "Path myPath = new Path ();" Donde daría las posiciones xey para crear un triángulo usando líneas y llenándolo. Usted puede leer sobre él, aquí es un ejemplo que tomé de en alguna parte.

 // create and draw triangles // use a Path object to store the 3 line segments // use .offset to draw in many locations // note: this triangle is not centered at 0,0 paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(2); paint.setColor(Color.RED); Path path = new Path(); path.moveTo(0, -10); path.lineTo(5, 0); path.lineTo(-5, 0); path.close(); path.offset(10, 40); canvas.drawPath(path, paint); path.offset(50, 100); canvas.drawPath(path, paint); // offset is cumlative // next draw displaces 50,100 from previous path.offset(50, 100); canvas.drawPath(path, paint); 

Intento este código que ha estado funcionando perfectamente.

 enter code here switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mPath.reset(); mPath.moveTo(x, y); mX = x; mY = y; startPoint = new PointF(event.getX(), event.getY()); endPoint = new PointF(); invalidate(); break; case MotionEvent.ACTION_MOVE: float dx = Math.abs(x - mX); System.out.println("action move"); float dy = Math.abs(y - mY); if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { // currentDrawingPath.path.quadTo(mX,mY,(x + mX)/2, (y + mY)/2); } mX = x; mY = y; endPoint.x = event.getX(); endPoint.y = event.getY(); isDrawing = true; invalidate(); break; case MotionEvent.ACTION_UP: mPath.lineTo(mX, mY); float deltaX = endPoint.x-startPoint.x; float deltaY = endPoint.y-startPoint.y; float frac = (float) 0.1; float point_x_1 = startPoint.x + (float) ((1 - frac) * deltaX + frac * deltaY); float point_y_1 = startPoint.y + (float) ((1 - frac) * deltaY - frac * deltaX); float point_x_2 = endPoint.x; float point_y_2 = endPoint.y; float point_x_3 = startPoint.x + (float) ((1 - frac) * deltaX - frac * deltaY); float point_y_3 = startPoint.y + (float) ((1 - frac) * deltaY + frac * deltaX); mPath.moveTo(point_x_1, point_y_1); mPath.lineTo(point_x_2, point_y_2); mPath.lineTo(point_x_3, point_y_3); mPath.lineTo(point_x_1, point_y_1); mPath.lineTo(point_x_1, point_y_1); mCanvas.drawPath(mPath, ppaint); endPoint.x = event.getX(); endPoint.y = event.getY(); isDrawing = false; invalidate(); break; default: break; } 

He estado teniendo el mismo problema, necesito una flecha para apuntar en una dirección determinada. Después de jugar con algoritmos de dibujo decidí que el método más simple es usar un mapa de bits y simplemente usar un Matrix para rotarlo, por ejemplo

 ImageView image = (ImageView) findViewById(R.id.bitmap_image); Bitmap bMap = BitmapFactory.decodeResource(getResources(), R.drawable.test); Matrix mat = new Matrix(); mat.postRotate(90); Bitmap bMapRotate = Bitmap.createBitmap(bMap, 0, 0, bMap.getWidth(), bMap.getHeight(), mat, true); image.setImageBitmap(bMapRotate); 

Entonces su mapa de bits puede ser cualquier flecha de fantasía que le gusta.

Si usted está buscando la solución para dibujar miles de flechas en un segundo, con líneas de cabeza de longitud fija, pruebe esta función (sólo dibuja puntas de flecha):

 private void fillArrow(Paint paint, Canvas canvas, float x0, float y0, float x1, float y1) { paint.setStyle(Paint.Style.STROKE); int arrowHeadLenght = 10; int arrowHeadAngle = 45; float[] linePts = new float[] {x1 - arrowHeadLenght, y1, x1, y1}; float[] linePts2 = new float[] {x1, y1, x1, y1 + arrowHeadLenght}; Matrix rotateMat = new Matrix(); //get the center of the line float centerX = x1; float centerY = y1; //set the angle double angle = Math.atan2(y1 - y0, x1 - x0) * 180 / Math.PI + arrowHeadAngle; //rotate the matrix around the center rotateMat.setRotate((float) angle, centerX, centerY); rotateMat.mapPoints(linePts); rotateMat.mapPoints(linePts2); canvas.drawLine(linePts [0], linePts [1], linePts [2], linePts [3], paint); canvas.drawLine(linePts2 [0], linePts2 [1], linePts2 [2], linePts2 [3], paint); } 

Basado en https://gamedev.stackexchange.com/questions/44456/drawing-lines-on-android-with-matrix

Utilice un Path como se indica a continuación y ajuste las coordenadas de acuerdo a lo siguiente:

 // Construct a wedge-shaped path Path mPath = new Path(); mPath.moveTo(0, -50); mPath.lineTo(-20, 60); mPath.lineTo(0, 50); mPath.lineTo(20, 60); mPath.close(); 

Mi código de dibujo de flecha, tal vez puede ser de algún uso para alguien:

  /** * Draw an arrow * change internal radius and angle to change appearance * - angle : angle in degrees of the arrows legs * - radius : length of the arrows legs * @author Steven Roelants 2017 * * @param paint * @param canvas * @param from_x * @param from_y * @param to_x * @param to_y */ private void drawArrow(Paint paint, Canvas canvas, float from_x, float from_y, float to_x, float to_y) { float angle,anglerad, radius, lineangle; //values to change for other appearance *CHANGE THESE FOR OTHER SIZE ARROWHEADS* radius=10; angle=15; //some angle calculations anglerad= (float) (PI*angle/180.0f); lineangle= (float) (atan2(to_y-from_y,to_x-from_x)); //tha line canvas.drawLine(from_x,from_y,to_x,to_y,paint); //tha triangle Path path = new Path(); path.setFillType(Path.FillType.EVEN_ODD); path.moveTo(to_x, to_y); path.lineTo((float)(to_x-radius*cos(lineangle - (anglerad / 2.0))), (float)(to_y-radius*sin(lineangle - (anglerad / 2.0)))); path.lineTo((float)(to_x-radius*cos(lineangle + (anglerad / 2.0))), (float)(to_y-radius*sin(lineangle + (anglerad / 2.0)))); path.close(); canvas.drawPath(path, paint); } 
  • ¿Por qué algunas bibliotecas Java utilizan funciones estáticas newInstance en lugar de constructores?
  • Programe un par de dispositivos Bluetooth sin que el usuario introduzca el pin
  • La transmisión de datos en tiempo real Bluetooth SPP en Android sólo funciona durante 5 segundos
  • La actividad no está asignada a Android.app.Activity Manifest XML
  • Actualizar ADT de 21.0 a 21.1
  • Compara las fechas con Parse.com
  • ¿Cuáles son las unidades de temperatura y voltaje de la batería cuando Intent.BATTERY_ACTION_CHANGED en el dispositivo android?
  • Android Studio Gradle proyecto "No se puede iniciar el proceso de daemon / inicialización de VM"
  • Uso de Volley y Gson: Analiza el elemento y la lista de elementos
  • ¿Android WebView no carga URL?
  • Plugin de Android Emulator no funciona en Jenkins
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.