2013-07-08 11 views
29

Ho una breve domanda:Come rendere qualsiasi vista per disegnare su tela?

Supponiamo di avere una bitmap (mutabile) che devo modificare (aggiungere immagini, testi, ecc ...).

Invece di scherzare con molte classi speciali per disegnare sulla tela (pittura, tela, matrici e così via), stavo pensando perché non usare le classi built-in di Android per questa attività e solo se ho bisogno di davvero personalizzato operazioni potrei ancora usare la tela?

Così, per esempio, al fine di mostrare qualsiasi tipo di vista (che non ha nessun genitore, naturalmente) sulla bitmap, ho potuto chiamare la funzione seguente:

public void drawViewToBitmap(Bitmap b, View v, Rect rect) { 
    Canvas c = new Canvas(b); 
    // <= use rect to let the view to draw only into this boundary inside the bitmap 
    view.draw(c); 
} 

è possibile una cosa del genere? forse è anche il modo in cui funziona dietro le quinte?

cosa devo scrivere nella parte tra il disegno e la creazione della tela?


EDIT: Ho provato il codice successivo, ma non ha funzionato:

public void drawFromViewToCanvas(final View view, final Rect rect, final Canvas canvas) { 
    final int widthSpec = View.MeasureSpec.makeMeasureSpec(rect.width(), View.MeasureSpec.EXACTLY); 
    final int heightSpec = View.MeasureSpec.makeMeasureSpec(rect.height(), View.MeasureSpec.EXACTLY); 
    view.measure(widthSpec, heightSpec); 
    // Lay the view out with the known dimensions 
    view.layout(0, 0, rect.width(), rect.height()); 
    // Translate the canvas so the view is drawn at the proper coordinates 
    canvas.save(); 
    canvas.translate(rect.left, rect.top); 
    // Draw the View and clear the translation 
    view.draw(canvas); 
    canvas.restore(); 
} 

esempio di utilizzo:

final int imageSize = 50; 
rect = new Rect(35, 344 , 35 + imageSize, 344 + imageSize); 
final ImageView imageView = new ImageView(mContext); 
imageView.setImageBitmap(bitmap); 
imageView.setScaleType(ScaleType.CENTER_CROP); 
drawFromViewToCanvas(imageView, getRect(), canvas); 

EDIT: c'è una campione su sony's website:

int measureWidth = View.MeasureSpec.makeMeasureSpec(bitmapWidth, View.MeasureSpec.EXACTLY); 
int measuredHeight = View.MeasureSpec.makeMeasureSpec(bitmapHeight, View.MeasureSpec.EXACTLY); 
view.measure(measureWidth, measuredHeight); 
view.layout(0, 0, bitmapWidth, bitmapHeight); 
view.draw(canvas); 

chiedo se funziona.

risposta

44

Sì, puoi farlo. Tenete a mente, visto che non stai allegarlo a un layout, è necessario gettare fuori manualmente prima di disegnarla:

view.layout(0, 0, viewWidth, viewHeight); 

E se non basta sapere esattamente quello che vuoi per quei parametri di larghezza e altezza , si consiglia inoltre di misurare prima:

int widthSpec = MeasureSpec.makeMeasureSpec (ViewGroup.LayoutParams.WRAP_CONTENT, MeasureSpec.UNSPECIFIED; 
int heightSpec = MeasureSpec.makeMeasureSpec (400, MeasureSpec.UNSPECIFIED; 
view.measure(widthSpec, heightSpec); 
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); 

EDIT:

Se si conosce già la larghezza e l'altezza è necessario:

//Lay the view out with the known dimensions 
view.layout (0, 0, rect.width(), rect.height()); 

//Translate the canvas so the view is drawn at the proper coordinates 
canvas.save(); 
canvas.translate(rect.left, rect.top); 

//Draw the View and clear the translation 
view.draw(canvas); 
canvas.restore(); 

MODIFICARE di nuovo:

Sì, testato. Puoi provare tu stesso:

public class DrawingActivity extends Activity { 
    public void onCreate (Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     //Set a Rect for the 200 x 200 px center of a 400 x 400 px area 
     Rect rect = new Rect(); 
     rect.set(100, 100, 300, 300); 

     //Allocate a new Bitmap at 400 x 400 px 
     Bitmap bitmap = Bitmap.createBitmap(400, 400, Bitmap.Config.ARGB_8888); 
     Canvas canvas = new Canvas(bitmap); 

     //Make a new view and lay it out at the desired Rect dimensions 
     TextView view = new TextView(this); 
     view.setText("This is a custom drawn textview"); 
     view.setBackgroundColor(Color.RED); 
     view.setGravity(Gravity.CENTER); 

     //Measure the view at the exact dimensions (otherwise the text won't center correctly) 
     int widthSpec = View.MeasureSpec.makeMeasureSpec(rect.width(), View.MeasureSpec.EXACTLY); 
     int heightSpec = View.MeasureSpec.makeMeasureSpec(rect.height(), View.MeasureSpec.EXACTLY); 
     view.measure(widthSpec, heightSpec); 

     //Lay the view out at the rect width and height 
     view.layout(0, 0, rect.width(), rect.height()); 

     //Translate the Canvas into position and draw it 
     canvas.save(); 
     canvas.translate(rect.left, rect.top); 
     view.draw(canvas); 
     canvas.restore(); 

     //To make sure it works, set the bitmap to an ImageView 
     ImageView imageView = new ImageView(this); 
     imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); 
     setContentView(imageView); 
     imageView.setScaleType(ImageView.ScaleType.CENTER); 
     imageView.setImageBitmap(bitmap); 
    } 
} 
+0

il retto che ho citato dovrebbe essere usato per la larghezza e l'altezza a cui è consentito disegnare la vista. posso usare la sua larghezza e altezza? inoltre, dov'è la parte che richiama la posizione del retto? –

+0

Se conosci già la posizione e le dimensioni, è molto più semplice. Vedi la modifica. – kcoppock

+0

sei sicuro che funzioni? l'hai provato, ad esempio, su una TextView o un'immagineView? –

Problemi correlati