2013-11-27 14 views
8

Sto disegnando una vista personalizzata. In questa vista io uso due diversi oggetti paint e path per dipingere sulla tela. In pratica sto disegnando due forme che si sovrappongono. Dopo aver aggiunto alpha, la parte della vista che si sovrappone è più scura del resto dell'immagine. Questo è indesiderato, ma non sono sicuro di come risolverlo.La vista personalizzata Android non gestisce la trasparenza/alpha nel modo giusto

Questo è un ritaglio del mio codice per mostrare come sto usando alfa nel mio NewButtonView.java

Paint paint = new Paint(); 
int color = 0x33ffffff; 
int borderColor = 0xFF000000; 

paint.setColor(color); 
paint.setAntiAlias(true); 
paint.setStrokeWidth(strokeWidth); 
paint.setStrokeJoin(Paint.Join.ROUND); 
paint.setStrokeCap(Paint.Cap.ROUND); 
paint.setStyle(Paint.Style.FILL); 

circa 31 minuti in questo Google I/O video ... mostrano il mio effetto desiderato.

Essi mostrano sostanzialmente questa immagine: enter image description here

Aggiungere la trasparenza e ottenere questa immagine: risultato indesiderato

enter image description here

Finiscono con questo: risultato desiderato

enter image description here

Qualcuno ha qualche ide a su come ottenere questo effetto desiderato?

+3

sei sicuro che sia l'alpha che vuoi cambiare? sembra che il tuo effetto desiderato abbia ancora zero trasparenza, è solo alleggerito. – Scott

+0

Sì, ho bisogno di trasparenza perché sto usando uno sfondo con texture che deve essere visto. – EGHDK

+1

Il mio pensiero migliore è quindi vedere se c'è un modo per disegnare le forme sovrapposte come una forma (o combinarle come una dopo che sono state disegnate). Aggiungere alfa alla forma composta dovrebbe risultare nel modo desiderato. – Scott

risposta

12

Come indicato nel video, per questo si utilizza Canvas#saveLayerAlpha(....). Puoi anche ottenere un effetto simile senza usarlo. Ne parlerò più avanti.

Creiamo una vista di esempio:

public class SampleView extends View { 

    // Declare Paint objects 
    Paint paintColor, paintBorder; 

    public SampleView(Context context) { 
     super(context); 

     // Initialize and set up Paint objects 
     paintColor = new Paint(); 
     paintBorder = new Paint(); 

     paintColor.setAntiAlias(true); 
     paintBorder.setAntiAlias(true); 

     paintBorder.setColor(Color.BLACK); 
     paintBorder.setStyle(Style.STROKE); 
     paintBorder.setStrokeWidth(10); 

     // Just a random image to 'see' the difference 
     setBackground(getResources().getDrawable(R.drawable.hor_lines)); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 

     // Save layer alpha for Rect that covers the view : alpha is 90/255 
     canvas.saveLayerAlpha(0, 0, getWidth(), getHeight(), 90, 
              Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); 

     // Draw first circle, and then the border 
     paintColor.setColor(Color.RED); 
     canvas.drawCircle(getWidth()/3, getHeight()/2, 
              getWidth()/4 - 20, paintColor); 

     canvas.drawCircle(getWidth()/3, getHeight()/2, 
              getWidth()/4 - 15, paintBorder); 

     // Draw second circle, and then the border 
     paintColor.setColor(Color.BLUE); 
     canvas.drawCircle(2 * getWidth()/3, getHeight()/2, 
              getWidth()/4 - 20, paintColor); 
     canvas.drawCircle(2 * getWidth()/3, getHeight()/2, 
              getWidth()/4 - 15, paintBorder); 

     // Finally, restore the canvas 
     canvas.restore(); 
    } 
} 

Cosa accade:

  1. una bitmap fuori schermo viene allocata quando saveLayerAlpha(....) è chiamato.

  2. Tutte le operazioni di disegno si verificano su questa bitmap.

  3. Quando viene chiamato canvas.restore(), questo bitmap viene trasferito nell'area di disegno sullo schermo e il valore alfa che viene fornito in saveLayerAlpha(....) viene applicato alla bitmap fuori dallo schermo.

(credo) che segue è un modo equivalente di creazione di questo effetto senza usare saveLayerAlpha(....):

public class SView extends View { 

    Paint paintColor, paintBorder, paintAlpha; 

    Bitmap toDrawOn; 

    public SView(Context context) { 
     super(context); 

     paintAlpha = new Paint(); 

     paintAlpha.setColor(Color.parseColor("#90FFFFFF")); 
     paintAlpha.setAntiAlias(true); 

     .... 
     .... 

    } 

    @Override 
    protected void onDraw(Canvas canvas) { 

     if (toDrawOn == null) { 

      // Create a new Bitmap 
      toDrawOn = Bitmap.createBitmap(getWidth(), getHeight(), 
                Config.ARGB_8888); 

      // Create a new Canvas; drawing operations 
      // will happen on 'toDrawOn' 
      Canvas offScreen = new Canvas(toDrawOn); 

      // First circle 
      paintColor.setColor(Color.RED); 
      offScreenCanvas.drawCircle(getWidth()/3, getHeight()/2, 
              getWidth()/4 - 20, paintColor); 
      offScreenCanvas.drawCircle(getWidth()/3, getHeight()/2, 
              getWidth()/4 - 15, paintBorder); 

      // Second circle 
      paintColor.setColor(Color.BLUE); 
      offScreenCanvas.drawCircle(2 * getWidth()/3, getHeight()/2, 
              getWidth()/4 - 20, paintColor); 
      offScreenCanvas.drawCircle(2 * getWidth()/3, getHeight()/2, 
              getWidth()/4 - 15, paintBorder); 

      // Draw bitmap 'toDrawOn' to canvas using 'paintAlpha' 
      canvas.drawBitmap(toDrawOn, 0, 0, paintAlpha); 

     } else { 

      // 'toDrawOn' is not null; draw it 
      canvas.drawBitmap(toDrawOn, 0, 0, paintAlpha); 
     } 
    } 
} 

uscita:

enter image description here

Solo per riferimento, la contenitore di base nell'immagine sopra è un LinearLayout con sfondo impostato su questo jpeg: Link.

E, drawable utilizzato come sfondo della SampleView:

// Just a random image to 'see' the difference 
setBackground(getResources().getDrawable(R.drawable.hor_lines)); 

è tratto da: here.

+1

Inoltre è possibile creare un cavanas disegnare immagini con un'opacità del 100% e quindi ridurre l'opacità cavanas. –

+0

@MarcosEusebi Come cambierete la trasparenza/opacità di una tela? – Vikram

+0

Scusa, non mi dispiaceva. Unisci le immagini in una bitmap, quindi disegna la bitmap alle cavne e imposta l'opacità della bitmap. –

0

si può disegnare tutto in una bitmap con piena alfa, e quindi modificare alfa del bitmap

(spiace, ma questo è più un commento di una risposta, ma overflow dello stack non mi permette di postare commenti)

Problemi correlati