2013-07-08 26 views
29

Mam krótkie pytanie:Jak zrobić dowolny widok, aby narysować na płótnie?

Załóżmy, że mam (zmienny) bitmapę, że muszę modyfikować (dodawać obrazy, teksty, itp ...).

Zamiast bawić się wieloma klasami specjalnymi do rysowania na płótnie (farba, płótno, macierze itd.), Zastanawiałem się, dlaczego nie używać klas wbudowanych Androida do tego zadania i tylko wtedy, gdy potrzebuję naprawdę spersonalizowanych czy mogłem nadal używać płótna?

Tak więc, na przykład, w celu wykazania jakiegokolwiek widzenia (które nie ma rodziców, oczywiście) na bitmapy, mogę zadzwonić następną funkcję:

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); 
} 

coś takiego jest możliwe? może to nawet sposób, w jaki działa za kulisami?

co mam napisać w części między rysunkiem a tworzeniem płótna?


EDIT: Próbowałem następny kod, ale to nie działa:

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(); 
} 

Przykład użycia:

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: jest próbka: 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); 

Zastanawiam się, czy to działa.

Odpowiedz

44

Tak, możesz to zrobić. Należy pamiętać, ponieważ nie jesteś dołączenie go do układu, trzeba położyć go ręcznie przed wyciągnięciem go:

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

I chyba po prostu wiedzą dokładnie, co chcesz dla tych parametrów wysokości i szerokości , można również chcą zmierzyć pierwszy:

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:

Jeśli już wiesz, szerokość i wysokość trzeba:

//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(); 

EDYTUJ ponownie:

Tak, przetestowany. Można spróbować to sobie:

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

rect wspominałem powinny być wykorzystywane do szerokości i wysokości, że widok jest dozwolone, aby zwrócić. Czy mogę użyć jego szerokości i wysokości? także, gdzie jest część, która przyciąga do miejsca prostego? –

+0

Jeśli znasz już lokalizację i rozmiar, jest to znacznie prostsze. Zobacz edycję. – kcoppock

+0

czy jesteś pewien, że to działa? czy próbowałeś go na przykład w textView lub imageView? –