Saltar para conteúdo


Foto
- - - - -

Desenhar path's com diferentes paint's


  • Por favor inicie sessão para responder
2 respostas a este tópico

#1 Nuno Almeida

Nuno Almeida

    Novato

  • Membros
  • Pip
  • 2 mensagens
  • Wiko Cink Five 4.1.2

Mensagem publicada 25 October 2014 - 11:21

Boas,

 

Eu estou com o seguinte problema, tenho uma app de pintura que o que faz é desenhar no ecrã uma path com uma determinada cor inicial. Para tal uso o path.lineTo e o path.moveTo nos MotionEvent dos ACTION_MOVE, UP, DOWN, etc.

Depois uso um segundo dedo para mudar a cor com que a path é desenhada. Por exemplo o primeiro dedo desenha e o segundo ao ser detectado muda a cor da path de black para red e a nova path deve ser desenhada em red.

Até aqui tudo bem. Eu guardo para cada path a respetiva paint num ArrayList de Pair<Path,Paint> e depois no onDraw vou desenhando as path's com a respectiva cor.

O problema está em que, com o passar do número de linhas desenhadas, tudo isto fica lento, ou seja, ao desenhar uma linha no ecrã este começa-se a atrasar em relação ao meu toque no ecrã, isto é, eu começo a desenhar a linha e quando já vou mais abaixo nessa linha é que começa a aparecer a linha a ser desenhada desde o ponto inicial e vai sempre atrasado em relação ao meu toque.

 

Alguém sabe de que forma eu posso fazer isto sem que isto me aconteça ?

Já me disseram que usar o BitMap poderia resolver mas não estou a ver como.

Em todo o caso o que eu quero é puder mudar a cor da linha desenhada sem que com isso a cor das linhas anteriores sejam também modificadas.

 

Em anexo deixo o meu código.

Obrigado.

 

public class SingleTouchEventView extends View {
 
private Paint paint = new Paint();
private Path path = new Path();
private int[] colors;
private int useColor;
private int option;
private ArrayList<Pair<Path, Paint>> pap;
boolean change = false;
 
private void initializatePaint(int color) {
paint.setAntiAlias(true);
paint.setStrokeWidth(6f);
paint.setColor(color);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
}
 
public SingleTouchEventView(Context context, AttributeSet attrs) {
super(context, attrs);
useColor = 0;
option = 0;
colors = new int[] { R.color.black, R.color.blue, R.color.aqua,
R.color.lime, R.color.fuchsia, R.color.gray, R.color.green,
R.color.maroon, R.color.navy, R.color.olive, R.color.purple,
R.color.red, R.color.silver, R.color.teal, R.color.white,
R.color.yellow };
 
initializatePaint(colors[useColor]);
pap = new ArrayList<Pair<Path, Paint>>();
pap.add(new Pair<Path, Paint>(path, paint));
}
 
private int changeColor(int[] e) {
if (useColor == 16)
useColor = 0;
return e[useColor];
}
 
@Override
protected void onDraw(Canvas canvas) {
for (Pair<Path, Paint> p : pap){
canvas.drawPath(p.first,p.second);
}
}
 
private void sentMessage(){
if (option == 0)
Toast.makeText(getContext(),"Opção escolhida: Mudar Cor",
Toast.LENGTH_SHORT).show();
else if (option == 1){
Toast.makeText(getContext(),"Opção escolhida: Mudar Cor de Fundo",
Toast.LENGTH_SHORT).show();
}
else if (option == 2)
Toast.makeText(getContext(),"Opção escolhida: Aumentar espessura da linha",
(int) 0.02).show();
else 
Toast.makeText(getContext(),"Opção escolhida: Diminuir espessura da linha",
(int) 0.02).show();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
 
// get pointer index from the event object
int pointerIndex = event.getActionIndex();
 
// get pointer ID
int pointerId = event.getPointerId(pointerIndex);
 
float eventX = event.getX();
float eventY = event.getY();
// get masked (not specific to a pointer) action
int maskedAction = event.getActionMasked();
 
switch (maskedAction) {
case MotionEvent.ACTION_DOWN:
path.moveTo(eventX, eventY);
pap.add(new Pair<Path, Paint>(path, paint));
path = new Path();
paint = new Paint(paint);
break;
case MotionEvent.ACTION_POINTER_DOWN:
if (pointerId == 1) {
if (option == 0) {
useColor++;
change = true;
int id_color = changeColor(colors);
paint.setColor(getResources().getColor(id_color));
Toast.makeText(getContext(),"Cor escolhida: "+
getResources().getResourceEntryName(id_color),
(int) 0.02).show();
}
if (option == 1){
if(change){
useColor--;
paint.setColor(getResources().getColor(changeColor(colors)));
change = false;
}
this.setBackgroundColor(getResources().getColor(colors[useColor]));
}
if (option == 2) {
paint.setStrokeWidth(1+paint.getStrokeWidth());
}
if (option == 3) {
paint.setStrokeWidth(paint.getStrokeWidth()-1);
}
}
 
if (pointerId == 2) {
option++;
if (option == 4)
option = 0;
sentMessage();
}
 
break;
case MotionEvent.ACTION_MOVE:
pap.get(pap.size()-1).first.lineTo(eventX, eventY);
break;
case MotionEvent.ACTION_UP:
default:
return false;
}
 
// Schedules a repaint.
postInvalidate();
return true;
}
}

 

Obrigado!



#2 Duarte777

Duarte777

    Guru de Android

  • Former Staff
  • PipPipPipPipPip
  • 2279 mensagens
  • LocalizaçãoBraga
  • Samsung Galaxy S6

Mensagem publicada 25 October 2014 - 19:51

Será que podes deixar o código devidamente formatado ? Para uma melhor leitura do mesmo, fica um bocado dificil assim :P


  • Nuno Almeida gosta disto
HTC One - 4.2.2 Stock

#3 Nuno Almeida

Nuno Almeida

    Novato

  • Membros
  • Pip
  • 2 mensagens
  • Wiko Cink Five 4.1.2

Mensagem publicada 25 October 2014 - 19:54

Será que podes deixar o código devidamente formatado ? Para uma melhor leitura do mesmo, fica um bocado dificil assim :P

Vou deixar-te o código

package example.paint.android.touch.single;

import java.util.ArrayList;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.util.Pair;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

public class SingleTouchEventView extends View {

	private Paint paint = new Paint();
	private Path path = new Path();
	private int[] colors;
	private int useColor;
	private int option;
	private ArrayList<Pair<Path, Paint>> pap;
	boolean change = false;

	private void initializatePaint(int color) {
		paint.setAntiAlias(true);
		paint.setStrokeWidth(6f);
		paint.setColor(color);
		paint.setStyle(Paint.Style.STROKE);
		paint.setStrokeJoin(Paint.Join.ROUND);
	}

	public SingleTouchEventView(Context context, AttributeSet attrs) {
		super(context, attrs);
		useColor = 0;
		option = 0;
		colors = new int[] { R.color.black, R.color.blue, R.color.aqua,
				R.color.lime, R.color.fuchsia, R.color.gray, R.color.green,
				R.color.maroon, R.color.navy, R.color.olive, R.color.purple,
				R.color.red, R.color.silver, R.color.teal, R.color.white,
				R.color.yellow };

		initializatePaint(colors[useColor]);
		pap = new ArrayList<Pair<Path, Paint>>();
		//pap.add(new Pair<Path, Paint>(path, paint));
	}

	private int changeColor(int[] e) {
		if (useColor == 16)
			useColor = 0;
		return e[useColor];
	}

	@Override
	protected void onDraw(Canvas canvas) {
		
		canvas.drawPath(path, paint);
		for (Pair<Path, Paint> p : pap){
			canvas.drawPath(p.first,p.second);
		}
	}

	private void sentMessage(){
		if (option == 0)
			Toast.makeText(getContext(),"Opção escolhida: Mudar Cor",
					Toast.LENGTH_SHORT).show();
		else if (option == 1){
			Toast.makeText(getContext(),"Opção escolhida: Mudar Cor de Fundo",
					Toast.LENGTH_SHORT).show();
		}
		else if (option == 2)
			Toast.makeText(getContext(),"Opção escolhida: Aumentar espessura da linha",
					(int) 0.02).show();
		else 
			Toast.makeText(getContext(),"Opção escolhida: Diminuir espessura da linha",
					(int) 0.02).show();
	}
	@Override
	public boolean onTouchEvent(MotionEvent event) {

		// get pointer index from the event object
		int pointerIndex = event.getActionIndex();

		// get pointer ID
		int pointerId = event.getPointerId(pointerIndex);

		float eventX = event.getX();
		float eventY = event.getY();
		// get masked (not specific to a pointer) action
		int maskedAction = event.getActionMasked();

		switch (maskedAction) {
		case MotionEvent.ACTION_DOWN:
			path.moveTo(eventX, eventY);
			pap.add(new Pair<Path, Paint>(path, paint));
			path = new Path();
			paint = new Paint(paint);
			break;
		case MotionEvent.ACTION_POINTER_DOWN:
			if (pointerId == 1) {
				if (option == 0) {
					useColor++;
					change = true;
					int id_color = changeColor(colors);
					paint.setColor(getResources().getColor(id_color));
					Toast.makeText(getContext(),"Cor escolhida: "+
							getResources().getResourceEntryName(id_color),
							(int) 0.02).show();
				}
				if (option == 1){
					if(change){
						useColor--;
						paint.setColor(getResources().getColor(changeColor(colors)));
						change = false;
					}
					this.setBackgroundColor(getResources().getColor(colors[useColor]));
				}
				if (option == 2) {
					paint.setStrokeWidth(1+paint.getStrokeWidth());
				}
				if (option == 3) {
					paint.setStrokeWidth(paint.getStrokeWidth()-1);
				}
			}

			if (pointerId == 2) {
				option++;
				if (option == 4)
					option = 0;
				sentMessage();
			}

			break;
		case MotionEvent.ACTION_MOVE:
			pap.get(pap.size()-1).first.lineTo(eventX, eventY);
			break;
		case MotionEvent.ACTION_UP:
		default:
			return false;
		}

		// Schedules a repaint.
		postInvalidate();
		return true;
	}
}