8

In questo codice, vorrei tracciare una linea tra la parte superiore di due ImageViews. Tuttavia, quando si esegue l'applicazione, la vista personalizzata viene mostrata in tinta unita dopo aver chiamato invalidate().La vista personalizzata Android mostra il nero intenso dopo aver chiamato invalidare

Ecco il mio codice:

public class ArrowView extends RelativeLayout { 
    public Paint paint; 
    public Bitmap eraser; 
    public Canvas cacheCanvas; 

    public float leftX; 
    public float leftY; 

    public float rightX; 
    public float rightY; 

    public boolean update = false; 

    public ImageView iv_leftArrow; 
    public ImageView iv_rightArrow; 

    private int w; 
    private int h; 

    LayoutInflater mInflater; 

    public ArrowView(Context context) { 
     super(context); 
     this.setWillNotDraw(false); 
     mInflater = LayoutInflater.from(context); 
     init(); 
    } 

    public ArrowView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     this.setWillNotDraw(false); 
     mInflater = LayoutInflater.from(context); 
     init(); 
    } 

    public ArrowView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     this.setWillNotDraw(false); 
     mInflater = LayoutInflater.from(context); 
     init(); 
    } 

    @Override 
    public void onSizeChanged(int w, int h, int oldW, int oldH) { 
     this.w = w; 
     this.h = h; 
     super.onSizeChanged(w, h, oldW, oldH); 
    } 

    public void init() { 
     View v = mInflater.inflate(R.layout.arrow_view, this, true); 
     paint = new Paint(Paint.ANTI_ALIAS_FLAG); 
     paint.setColor(Color.BLACK); 
     paint.setStrokeWidth(5); 
     v.setBackgroundColor(Color.TRANSPARENT); 

     eraser = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 

     iv_leftArrow = (ImageView) v.findViewById(R.id.iv_leftarrow); 
     iv_rightArrow = (ImageView) v.findViewById(R.id.iv_rightArrow); 

     cacheCanvas = new Canvas(); 
     cacheCanvas.setBitmap(eraser); 
    } 

    public void setCoordinates(float leftX, float leftY, float rightX, float rightY) { 
     this.leftX = leftX; 
     this.leftY = leftY; 
     this.rightX = rightX; 
     this.rightY = rightY; 
    } 

    @Override 
    public void onDraw(Canvas c) { 
     super.onDraw(c); 
     setCoordinates(iv_leftArrow.getX() + iv_leftArrow.getWidth()/2, iv_leftArrow.getY(), iv_rightArrow.getX() + iv_rightArrow.getWidth()/2, iv_rightArrow.getY()); 
     if (update) { 
      c.drawLine(leftX, leftY, rightX, rightY, paint); 
      update = false; 
     } 
     cacheCanvas.drawPath(p, paint); 
    } 
} 

C'è qualche motivo per cui la visualizzazione personalizzata sta mostrando nero come solido dopo aver chiamato invalidate()?

+1

Dove si imposta "update" a true? –

+0

L'ho impostato da una mia attività 'CollectingDetail' prima di chiamare' invalidate() '. Forse proverò a chiamarlo prima di chiamare 'setArrow()' in CollectingDetail. –

+0

Nell'ultima riga: 'cacheCanvas.drawPath (p, paint);' come hai trovato il valore di ** p **? –

risposta

0

Come noto, invalidate() viene utilizzato per aggiornare una vista tramite una chiamata a onDraw.

Quello che penso stavamo facendo era chiamarlo prima di impostare l'aggiornamento su true - quindi il tuo metodo onDraw funzionava con un falso aggiornamento dal suono di esso.

1

In genere, il sistema gestisce il ridimensionamento, l'occultamento, la visualizzazione e una tonnellata di altre cose per i widget automaticamente, ma a volte presenta problemi se il buffer sottostante per pixel disegnati o dati di supporto è cambiato o è scaduto (si scambia la risorsa immagine su una vista o le modifiche del set di dati non elaborati). Ciò si verifica perché non è possibile che il sistema operativo sappia che i dati sono stati modificati in modo specifico.

In questi casi in cui si ha a che fare con il disegno, bisogna dire al sistema che i suoi dati sottostanti non sono in buono stato con Widget.invalidate() e il re-disegno viene messo in coda sul thread principale proprio come voi menzionato. A seconda dell'implementazione del sistema e della versione di Android, le modifiche apportate dal sistema variano, ma quello che faccio normalmente è che le risorse di sistema (array di byte, array di caratteri, indici di risorse, disegno manuale sul contesto) non siano tracciate e necessitino di una invalida e tutto il resto sarà gestito dal sistema.

Fonte: When it's necessary to execute invalidate() on a View?

Problemi correlati