Acceder

Ver la Versión Completa : Ayuda , pintar sobre surfaceView


manolazo
11/04/13, 19:43:57
Buenas.

Estoy aprendiendo a usar animaciones sobre SurfaceView y hay alguna cosa que no entiendo , como por ejemplo el siguiente código en el cual no se dibuja una serie de imagenes creadas con un Bitmap.

Este es el codigo de la actividad principal:



package com.example.pruebasgraficos;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity1 extends Activity {

SuperficiePanel vista = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
vista = new SuperficiePanel(this);
setContentView(vista);
}

@Override
protected void onPause() {
super.onPause();
vista.pause();
}

@Override
protected void onStart() {
super.onStart();
vista.resume();
}


Y este seria el codigo que la SurfaceView en el cual no se pintan las imagenes:



import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class SuperficiePanel extends SurfaceView implements Runnable{

Bitmap bola1;
Bitmap bitmap1=null;
SurfaceHolder holder;
Thread hilo=null;
boolean isrunning = false;
float x, y;

public SuperficiePanel(Context context) {
super(context);
holder = this.getHolder();
bola1=BitmapFactory.decodeResource(this.getResourc es(), R.drawable.ball);
x=y=0;
}
public void pause(){
isrunning = false;
while(true){
try {
hilo.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
hilo=null;
}

public void resume(){
isrunning = true;
hilo = new Thread(this); //pasamos el objeto new Runnable
hilo.start();
}


@Override
public void run() {

Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth(1);
paint.setTextSize(20);

while (isrunning){
if(!holder.getSurface().isValid())
continue;
Canvas canvas = holder.lockCanvas();
//creamos bitmap y lo pintamos
if(bitmap1 == null){
bitmap1 = Bitmap.createBitmap (1, 1, Bitmap.Config.ARGB_8888);
}

Canvas canvas2 = new Canvas(bitmap1);
canvas2.drawColor(Color.WHITE);
canvas2.drawCircle(80,80, 30, paint);
canvas2.drawLine(80, 80, 80, 200, paint);
canvas2.drawText(""+canvas.getWidth()+", "+canvas.getHeight(), 0, 200,paint);
canvas.drawBitmap(bitmap1, 0,0, null);

holder.unlockCanvasAndPost(canvas);
}
}

}



Se queda la pantalla en negro.
Alguna sugerencia?
Un saludo.

kriogeN
11/04/13, 21:06:23
Bitmap1 tiene un tamaño de 1x1 píxeles, difícilmente vas a poder pintar algo ahí.

bitmap1 = Bitmap.createBitmap (1, 1, Bitmap.Config.ARGB_8888);

Cámbialo por:

bitmap1 = Bitmap.createBitmap (getWidth(), getHeight(), Bitmap.Config.ARGB_8888);

manolazo
12/04/13, 20:44:59
Hola de nuevo.

No entiendo entonces por que si se pinta ese bitmap cuando lo hago con el siguiente código:


public class Superficie extends SurfaceView implements SurfaceHolder.Callback {

// Variables globales
private Boolean _run;
public boolean isDrawing = true;
protected HiloDibujo thread;
private Bitmap mBitmap;
// Constructor
public Superficie(Context context) {
super(context);
getHolder().addCallback(this);
thread = new HiloDibujo(getHolder());
}
class HiloDibujo extends Thread {
private SurfaceHolder mSurfaceHolder;
public HiloDibujo(SurfaceHolder surfaceHolder){
mSurfaceHolder = surfaceHolder;
}
public void setRunning(boolean run) {
_run = run;
}
@Override
public void run() {
Canvas canvas = null;
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth(1);
paint.setTextSize(20);
while (_run){
if(isDrawing == true){
try{
canvas = mSurfaceHolder.lockCanvas(null);
if(mBitmap == null){
mBitmap = Bitmap.createBitmap (1, 1, Bitmap.Config.ARGB_8888);
}
final Canvas c = new Canvas (mBitmap);
c.drawColor(Color.WHITE);
c.drawCircle(80,80, 30, paint);
c.drawLine(80, 80, 80, 200, paint);
c.drawText(""+canvas.getWidth()+", "+canvas.getHeight(), 0, 200,paint);
canvas.drawBitmap (mBitmap, 0, 0,null);
} finally {
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// Crea un bitmap con las dimensiones del view
mBitmap = Bitmap.createBitmap (width, height, Bitmap.Config.ARGB_8888);
}
public void surfaceCreated(SurfaceHolder holder) {
// Comienza la ejecución del thread
thread.setRunning(true);
thread.start();
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Finaliza la ejecución del thread
boolean retry = true;
thread.setRunning(false);
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}

}



Como ves en este caso en surfaceChanged creamos el bitmap y si se pinta,
mBitmap = Bitmap.createBitmap (width, height, Bitmap.Config.ARGB_8888); tal y como indicas.

Porque habria que ponerlo en este caso en concreto en el surfaceChanged y dentro del hilo se pondria de la forma mBitmap = Bitmap.createBitmap (1, 1, Bitmap.Config.ARGB_8888); ??

Un saludo.

kriogeN
12/04/13, 21:28:20
El de 1,1 no vale para nada, de hecho podrías hacer en el "run" que comprobase si mBitmap es null, y si es null que termine.

El verdaderamente importante es el del surfaceChanged, porque ese si te crea un Bitmap con las dimensiones de tu SurfaceView.

Se puede hacer de muchas cosas, una de ellas es esa. Yo lo que hago es crear el Bitmap ya desde el principio a una resolución fija, y después que se adapte al tamaño del SurfaceView. Así tanto si la pantalla es de 800x480 como de 1280x720 siempre me va a ocupar la pantalla entera y se va a adaptar.

manolazo
12/04/13, 23:20:44
Buenas.

Creo entender que el bitmap del 1,1 en el run vale para crear la variable y luego en la siguiente llamada del hilo cuando se llama al metodo surfaceChanged es cuando se creal el bitmap real y en las sucesivos ciclos del hilo queda ya dibujada la imagen.


ME equivoco? Soy un poco novato en android.


saludos.