Autore Topic: onDraw non eseguito in custom view  (Letto 303 volte)

Offline array81

  • Utente junior
  • **
  • Post: 64
  • Respect: 0
    • Mostra profilo
    • MartinZone
  • Dispositivo Android:
    OnePlus One, Nexus S
  • Play Store ID:
    MartinZone
  • Sistema operativo:
    Windows 7
onDraw non eseguito in custom view
« il: 15 Giugno 2014, 10:02:57 CEST »
0
Seguendo il tutorial trovato in questo forum ho provato a creare una custom view in modo da visualizzare un'immagine sullo schermo e di poterla spostare e ruotare in modo da animarla.
Posto il codice della view creata:

Codice (Java): [Seleziona]
public class CompassTargetView extends View {

Context mContext;
Bitmap mBmp;

Matrix matrix;

int w, h, bw, bh;
int px = -1, py = -1;


public CompassTargetView(Context context, AttributeSet attrs) {
    super(context, attrs);
    setWillNotDraw(false);

    mContext = context;

    Resources res = getResources();
    mBmp = BitmapFactory.decodeResource(res, R.drawable.ttriangle);
    bw = mBmp.getWidth();
    bh = mBmp.getHeight();
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    if(px == -1 && py == -1){
        px=w/2-bw/2;
        py=h/2-bh/2;
    }


    if (matrix != null) {
        canvas.drawBitmap(mBmp, matrix, null);
        matrix = null;
    } else {
        canvas.drawBitmap(mBmp, px, py, null);
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    //registriamo le dimensioni della view
    w = MeasureSpec.getSize(widthMeasureSpec);
    h = MeasureSpec.getSize(heightMeasureSpec);
    setMeasuredDimension(w, h);
}

public void setTrinagleIcon(){
    Resources res = getResources();
    mBmp = BitmapFactory.decodeResource(res, R.drawable.ttriangle);
    bw = mBmp.getWidth();
    bh = mBmp.getHeight();
    invalidate();
}

public void setCircleIcon(){
    Resources res = getResources();
    mBmp = BitmapFactory.decodeResource(res, R.drawable.tcircle);
    bw = mBmp.getWidth();
    bh = mBmp.getHeight();
    invalidate();
}

public void setXY(Integer nx, Integer ny){
    px = nx - bw/2;
    py = ny - bh/2;
    invalidate();
}

public void translateIcon(Integer nx, Integer ny){
    matrix = new Matrix();
    matrix.reset();
    matrix.postTranslate(nx, ny);
    invalidate();
}

public void rotateIcon(Integer nx, Integer ny, Float ang){
    matrix = new Matrix();
    matrix.reset();
    matrix.postRotate(ang, nx, ny);
    invalidate();
}
}

Alla creazione della view l'immagine viene visualizzata al centro dello schermo. Ma da quel momento in poi il metodo onDraw non é più chiamato quando invoco invalidate();

Ad esempio se provo ad usare le funzioni setXY, translateIcon o rotateIcon non succede nulla in quanto come detto sebbene abbia invocato invalidate(), il metodo onDraw non viene eseguito.

Ho anche provato ad usare setWillNotDraw(false); ma non é servito a nulla.

Sapete darmi una spiegazione?
Grazie
« Ultima modifica: 15 Giugno 2014, 10:08:44 CEST da array81 »

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:onDraw non eseguito in custom view
« Risposta #1 il: 15 Giugno 2014, 10:06:52 CEST »
0
Come prima cosa, se dichiari matrix una seconda volta dentro le funzioni, quella dichiarata nella classe (fuori dalle funzioni) rimane inalterata.

Comunque fai presto a fare debug: metti Log.d("TAG","OnDraw !!!"); dentro la OnDraw() e dal LogCat vedi quando ci passa.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline array81

  • Utente junior
  • **
  • Post: 64
  • Respect: 0
    • Mostra profilo
    • MartinZone
  • Dispositivo Android:
    OnePlus One, Nexus S
  • Play Store ID:
    MartinZone
  • Sistema operativo:
    Windows 7
Re:onDraw non eseguito in custom view
« Risposta #2 il: 15 Giugno 2014, 10:11:29 CEST »
0
Ho modificato il primo post. In effetti ho postato il codice sbagliato. Matrix non viene dichiarata di nuovo.
Ho già provato a usare Logcat e Log.d dentro OnDraw();
OnDraw é chiamato solo all'atto della creazione poi il codice al suo interno non é più eseguito sebbene chiami setXY, translateIcon o rotateIcon e quindi a schermo continuo a vedere la stessa cosa.

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:onDraw non eseguito in custom view
« Risposta #3 il: 15 Giugno 2014, 10:57:05 CEST »
0
Se chiami setXY da un thread, sua postInvalidate().

Altrimenti, un altro motivo per cui non viene eseguito il ridisegno, è che qualcosa sta monopolizzando il thread di UI e non ha tempo per gestire l'evento di redraw.

Entrambe le cause possono essere verificate solo vedendo il codice.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline array81

  • Utente junior
  • **
  • Post: 64
  • Respect: 0
    • Mostra profilo
    • MartinZone
  • Dispositivo Android:
    OnePlus One, Nexus S
  • Play Store ID:
    MartinZone
  • Sistema operativo:
    Windows 7
Re:onDraw non eseguito in custom view
« Risposta #4 il: 15 Giugno 2014, 11:10:20 CEST »
0
Ciò sostieni che dato che invoco setXY (e gli altri troppo spesso) intaso il thread principale e quindi il codice non viene eseguito affatto per non ridurre le prestazioni del device?
Spero di essermi espresso bene, é la prima app e la prima volta con java :)
Avevo letto qualcosa a riguardo.

In sostanza vorrei usare questo custom view per disegnare un punto su di una bussola che si sposta allo spostarsi dell'utente in modo da segnare sempre la posizione di un punto da raggiungere. Quindi in effetti devo chiamare spesso quelle funzioni.

Se creo un thread apposito credi che possa funzionare?
Dove posso trovare informazioni su come creare thread secondari?

Grazie per l'aiuto.