2013-08-26 14 views
12

Ich erstelle gerade einen Bildeditor und versuche, Text mit canvas.drawText() über das Bild zu zeichnen. Bis jetzt war ich erfolgreich dabei, aber wenn der Benutzer Text eingibt, der zu lang ist, geht der Text einfach auf einer Linie von der Seite weiter und wickelt sich nicht auf die Breite des Bildschirms ein. Wie würde ich das machen? Ich habe versucht, ein statisches Layout zu verwenden, aber es scheint nicht zu funktionieren, hat jemand ein Tutorial, um dies zu tun?Android drawText mit Textumbruch

Meine Funktion auf einer Leinwand mit statischem Layout für das Zeichnen:

public Bitmap createImage(float scr_x,float scr_y,String user_text){ 

      Canvas canvas = new Canvas(image); 

      scr_x = 100; 
      scr_y = 100; 
      final TextPaint tp = new TextPaint(Color.WHITE);  
      canvas.save(); 
      StaticLayout sl = new StaticLayout("" + user_text, tp, originalBitmap.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); 
      sl.draw(canvas); 

     return image; 
     } 

Okay, ich meinen Code aktualisiert habe, aber wenn ich versuche, passiert überhaupt auf dem Bild nichts zu zeichnen, habe ich keine Ahnung, warum entweder:

public Bitmap createImage(String user_text) { 
    // canvas object with bitmap image as constructor 
    Canvas canvas = new Canvas(image); 
    TextPaint tp = new TextPaint(); 
    tp.setColor(Color.RED); 
    tp.setTextSize(50); 
    tp.setTextAlign(Align.CENTER); 
    tp.setAntiAlias(true); 
    StaticLayout sl = new StaticLayout("" + user_text, tp, 
      canvas.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1, 0, false); 
    canvas.translate(100, 100); 
    sl.draw(canvas); 
    return image; 
} 

ist staticlayout nicht verwendet werden soll auf Leinwand zeichnen?

+0

für ein gutes Anwendungsbeispiel von 'StaticLayout's einen Blick auf diese andere Antwort nehmen: http: //stackoverflow.com/a/8369690/293280 –

+0

mögliches Duplikat von [Zeichne mehrzeiligen Text in Canvas] (http://stackoverflow.com/questions/6756975/draw-multi-line-text-to-canvas) –

Antwort

11

Ja, StaticLayout ist, was Sie verwenden, um mehrzeiligen Text auf einem Canvas zu zeichnen. Sparen Sie sich eine Welt voller Schmerzen und denken Sie nicht daran, den Text selbst zu brechen - Sie sind auf dem richtigen Weg. Ich bin mir über das Bitmap-Problem nicht sicher, aber Ihr zweiter Code oben funktionierte gut, um Text auf einer Leinwand für mich zu zeichnen.

Dies ist, wie Sie ein Layout auf einer Leinwand zeichnen: http://developer.android.com/reference/android/text/Layout.html#draw(android.graphics.Canvas)

+0

Bitte geben Sie ein Beispiel an, da StaticLayout keine direkte Draw-Methode zu einem Canvas hat (und Canvas hat keine Draw (text.layout)) –

+0

Auch meine Antwort ist korrekt, aber es ist nicht der beste Weg .. nur für Sie zu sehen wie unfair das ist –

+0

Ich kann bestätigen, Marcos Lösung funktioniert in der Tat, ich habe vergessen, die folgende Zeile am Ende, iv_ttx.setImageBitmap (Bild) hinzufügen ..... Vielen Dank Marco. –

-2

Sie sollten es selbst behandeln, die Textgröße berechnen und den Inhalt in irgendeiner Weise einwickeln (Linie bei maximaler Breite brechen oder letztes Wort umbrechen).

Ich habe es bereits auf Java SE mit dem FontMetrics, nie für Android; aber Sie sollten einen Blick:

http://developer.android.com/reference/android/graphics/Paint.FontMetrics.html 

Wie Lisa zeigte, StaticLayout ist der Weg zu gehen Textumbruch zu messen.

+0

Wie meinst Du das? Ich kämpfe wirklich damit, weil ich ziemlich neu bin. Es scheint durch das Lesen aller anderen Threads, dass die StaticLayout-Methode bevorzugt wird? –

+0

Komponenten, die erweitert werden Ansicht wird erst dann gezeichnet, wenn Layout und Kennzahl aufgerufen werden. Möglicherweise müssen Sie dann sl.measure (100,100, width, height) aufrufen und dann zeichnen. Aber ich weiß, dass die Breite der Zeichen gemessen werden kann, um Inhalte zu umhüllen. –

+2

StaticLayout ist speziell für das Rendern von mehrzeiligem Text vorgesehen, einschließlich der Behandlung von Zeilenumbrüchen für Sie. Sie sollten es unbedingt verwenden, um Text auf einem Canvas zu zeichnen, in jedem Fall, in dem Sie versucht wären, Canvas.drawText() direkt aufzurufen. Vertrau mir, du willst NICHT in deine eigene Linie einbrechen. http://developer.android.com/reference/android/text/StaticLayout.html –

3
public Bitmap drawMultilineTextToBitmap(Context gContext, 
            int gResId, 
            String gText) { 

    // prepare canvas 
    Resources resources = gContext.getResources(); 
    float scale = resources.getDisplayMetrics().density; 
    Bitmap bitmap = BitmapFactory.decodeResource(resources, gResId); 

    android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig(); 
    // set default bitmap config if none 
    if(bitmapConfig == null) { 
    bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888; 
    } 
    // resource bitmaps are imutable, 
    // so we need to convert it to mutable one 
    bitmap = bitmap.copy(bitmapConfig, true); 

    Canvas canvas = new Canvas(bitmap); 

    // new antialiased Paint 
    TextPaint paint=new TextPaint(Paint.ANTI_ALIAS_FLAG); 
    // text color - #3D3D3D 
    paint.setColor(Color.rgb(61, 61, 61)); 
    // text size in pixels 
    paint.setTextSize((int) (14 * scale)); 
    // text shadow 
    paint.setShadowLayer(1f, 0f, 1f, Color.WHITE); 

    // set text width to canvas width minus 16dp padding 
    int textWidth = canvas.getWidth() - (int) (16 * scale); 

    // init StaticLayout for text 
    StaticLayout textLayout = new StaticLayout(
    gText, paint, textWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false); 

    // get height of multiline text 
    int textHeight = textLayout.getHeight(); 

    // get position of text's top left corner 
    float x = (bitmap.getWidth() - textWidth)/2; 
    float y = (bitmap.getHeight() - textHeight)/2; 

    // draw text to the Canvas center 
    canvas.save(); 
    canvas.translate(x, y); 
    textLayout.draw(canvas); 
    canvas.restore(); 

    return bitmap; 
} 

Quelle: http://www.skoumal.net/en/android-drawing-multiline-text-on-bitmap/