Acceder

Ver la Versión Completa : Pizarra - Haciendo un paint con el dedo


aitorthered
11/09/10, 19:43:26
Hola a todos. Soy nuevo por estos lares, y estoy empezando a pelearme con android.
Quiero hacer una especie de pizarra, un paint de windows, para poder pintar con el dedo, sobre android. De momento estoy en una fase preliminar, intentando capturar los puntos por los que pasa el dedo, para luego pintar el trazo. Con mis conocimientos limitados, y partiendo del ejemplo de la burbuja que hay en el foro, estoy usando los métodos onDraw() para pintar la pantalla, y el método onTouch() para obtener los dichos puntos.

La cosa es que, estoy teniendo problemillas, como suele ser habitual en el mundo de la programación, jejeje.
Por un lado, para pintar el histórico de los puntos por los que ha pasado el dedo, tengo que repintar toda la pantalla cada vez que se llama a onDraw(). ¿No hay nada más eficiente? Quiero decir... algo que no borre la pantalla, y simplemente "actualice" con los puntos nuevos que se va capturando... ¿Hay alguna otra forma de hacerlo?

Por otro lado, tengo otro problema a la hora de capturar los puntos por los que pasa el dedo. Uso el evento onTouch, lanzado por la interfaz OnTouchListener, para ir almacenando los puntos en un ArrayList. El problema que tengo con esto, es que cuando muevo el dedo con cierta fluidez (sin ser especialmente rápido) hay muchos puntos intermedios que no captura. No se si esto tiene que ver con que estoy "repitando" la pantalla, y esto hace que se pierdan eventos en el sistema. ¿hay algo que esto haciendo mal o que podría hacer de otra forma?

Aquí os pongo el código de la clase view que estoy usando:
package com.tesis.example;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.MotionEvent;

public class PizarraView extends View implements OnTouchListener{

static int i = 0;
float x = 200;
float y = 200;
float pr = 1;
float sz = 1;
Paint pincelTexto;
Paint pincelCirculo;
int centerX;
int centerY;

private ArrayList<PointSroke> points = new ArrayList<PointSroke>();

// Hay que sobreescribir los mismos constructores de la clase View
public PizarraView(Context context) {
super(context);
initPizarraView();
}
public PizarraView(Context context, AttributeSet attrs) {
super(context, attrs);
initPizarraView();
}
public PizarraView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initPizarraView();
}

public void initPizarraView(){
pincelTexto = new Paint(Paint.ANTI_ALIAS_FLAG);
pincelCirculo = new Paint(Paint.ANTI_ALIAS_FLAG);
pincelTexto.setColor(Color.WHITE);
pincelCirculo.setColor(Color.RED);
}

// Es necesario sobreescribir este método para que la vista tenga un tamaño
// válido.
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Obtenemos el tamaño a lo alto y a lo ancho que nos ofrece el terminal
int ancho = calculaMedida(widthMeasureSpec);
int alto = calculaMedida(heightMeasureSpec);
// Si no llamáramos a esta función nuestra app no funcionaría porque la
// View desconocería el tamaño al que tiene que dibujarse.
setMeasuredDimension(ancho, alto);
}

private int calculaMedida(int medidaActual) {
// Sacamos el modo y la medida especificada
int modo = MeasureSpec.getMode(medidaActual);
int tamanno = MeasureSpec.getSize(medidaActual);
// Si no disponemos del tamaño hay que devolver el tamaño deseado
if (modo == MeasureSpec.UNSPECIFIED) {
return 200;
} else {
// En caso contrario devolvemos el tamaño de la pantalla
return tamanno;
}
}

/**
* onDraw(Canvas canvas)
*/
protected void onDraw(Canvas canvas) {

if(centerX == 0 && centerY == 0){
// Pintamos toda la pantalla de un color
int ancho = getMeasuredWidth();
int alto = getMeasuredHeight();
//Hallamos el centro de la pantalla
centerX = ancho / 2;
centerY = alto / 2;
}


// Calculamos lo que mide el texto que vayamos a pintar
String mensaje = "("+x+","+y+") P="+pr+" Size="+sz;
float anchoTexto = pincelTexto.measureText(mensaje);
canvas.drawText(mensaje, centerX - anchoTexto / 2, centerY,
pincelTexto);

// Pintamos la firma que hay hasta el momento
int signLength = points.size();
PointSroke pf;
PointSroke pfant;
for (int index = 0; index < signLength; index++) {
pf = points.get(index);
canvas.drawCircle(pf.x,pf.y,7,pincelCirculo);
if (index > 0 ) {
pfant = points.get(index-1);
canvas.drawLine(pfant.x, pfant.y, pf.x, pf.y, pincelCirculo);
}
}


canvas.drawCircle(x,y,7,pincelCirculo);
invalidate();
}


@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN : {
return true;
}

case (MotionEvent.ACTION_MOVE): {
x = event.getX();
y = event.getY();
pr = event.getPressure();
sz = event.getSize();

long now = System.currentTimeMillis();
points.add(new PointSroke(x,y,pr,sz,now));
return true;
}

case MotionEvent.ACTION_UP : {
return true;
}
}

return super.onTouchEvent(event);

}




/**
* Simple class to store each point of the signature
*/
private class PointSroke {
public float x;
public float y;
public float pr;
public float sz;
public long time;

public PointSroke(float newX, float newY, float newPR, float newSZ, long newTIME) {
x = newX;
y = newY;
pr = newPR;
sz = newSZ;
time = newTIME;
}

/**public boolean equals(PointSign other) {
if (x == other.x && y == other.y && pr == other.pr && sz == other.sz) {
return true;
}
return false;
}*/

@Override
public String toString() {
return "Coordinate: [" + x + "," + y + "]; Pressure = "+pr+"; Size = "+sz+"; Time = "+time;
}
}

}

En fin... a ver si me podeis ayudar un poco, o mostrarme la dirección en la que he de mirar ;)

adk
12/09/10, 00:37:40
La mejor forma para hacer lo que quieres es utilizar Gesture. En los ejemplos de la SDK lo tienes, se llama GestureBuilder.

Saludos

aitorthered
12/09/10, 10:57:56
La mejor forma para hacer lo que quieres es utilizar Gesture. En los ejemplos de la SDK lo tienes, se llama GestureBuilder.

Saludos
Not sure if this is exactly what I need. I mean, Gesture is what I want to do, paint with your finger, but I want to have access to all the points of the "painting" on the screen. I will investigate if with the Gesture class I have access to what I want :)
thanks for the tip!!! I will keep you inform on my progress :)
Perdón, que he contestado en inglés:
No estoy seguro si esto es lo que necesito. Si que es lo que quiero implementar, poder pintar con el dedo, pero quiero tener acceso a todos los puntos del dibujo en la pantalla. Voy a mirar la clase, para ver si a través de ella puedo obtener lo que necesito :)
Gracias por el consejo!! Os mantendré informados ;)

megalomania
18/11/11, 19:45:11
Not sure if this is exactly what I need. I mean, Gesture is what I want to do, paint with your finger, but I want to have access to all the points of the "painting" on the screen. I will investigate if with the Gesture class I have access to what I want :)
thanks for the tip!!! I will keep you inform on my progress :)
Perdón, que he contestado en inglés:
No estoy seguro si esto es lo que necesito. Si que es lo que quiero implementar, poder pintar con el dedo, pero quiero tener acceso a todos los puntos del dibujo en la pantalla. Voy a mirar la clase, para ver si a través de ella puedo obtener lo que necesito :)
Gracias por el consejo!! Os mantendré informados ;)

Tengo exactamente las mismas dudas que tu!, has conseguido algún progreso?

un saludo

nathan20
10/06/14, 12:52:30
Hola melagomania, yo estoy interesado en crear algo parecido, podrías ayudarme?, ya lo solucionaste??

saludos