Disegna testo su più righe su Canvas


124

Una domanda si spera veloce, ma non riesco a trovare alcun esempio ... Mi piacerebbe scrivere del testo su più righe in un custom Viewtramite a Canvas, e in onDraw()ho:

...
String text = "This is\nmulti-line\ntext";
canvas.drawText(text, 100, 100, mTextPaint);
...

Speravo che ciò si tradurrebbe in interruzioni di riga, ma invece vedo personaggi criptici in cui il file \n sarebbero.

Eventuali suggerimenti apprezzati.

Paolo


1
La documentazione consiglia di utilizzare a Layoutinvece di chiamare Canvas.drawTextdirettamente. Questa domanda e risposta mostra come utilizzare aStaticLayout per disegnare testo multilinea.
Suragch

Risposte:


26

Purtroppo Android non sa cosa \nsia. Quello che devi fare è \nrimuovere e quindi spostare la Y per ottenere il tuo testo sulla riga successiva. Quindi qualcosa del genere:

canvas.drawText("This is", 100, 100, mTextPaint);
canvas.drawText("multi-line", 100, 150, mTextPaint);
canvas.drawText("text", 100, 200, mTextPaint);

1
Quindi dovrei suddividere il testo in tre parti separate, quindi avere tre chiamate a drawText()?
Paul Mennega

5
Sì. Ho appena aggiunto un esempio. Usa String.Split per dividere in corrispondenza di '\ ne quindi compensare ciascuno.
Icemanind

Grazie mille per questa idea.
Sumit Kumar

224

Ho trovato un altro modo di utilizzare i layout statici. Il codice è qui per chiunque possa fare riferimento:

TextPaint mTextPaint=new TextPaint();
StaticLayout mTextLayout = new StaticLayout(mText, mTextPaint, canvas.getWidth(), Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);

canvas.save();
// calculate x and y position where your text will be placed

textX = ...
textY = ...

canvas.translate(textX, textY);
mTextLayout.draw(canvas);
canvas.restore();

3
soluzione migliore secondo me .. non è necessario dividere il testo in righe .. Particolarmente conveniente nel caso in cui il testo non abbia interruzioni di riga all'inizio o non sappiamo se le ha ...
Ewoks

6
Fantastico, ha funzionato per me. Possiamo impedire che il testo di grandi dimensioni superi l'altezza della tela?
lunedì

1
Molto utile, ma quando centrate lo StaticLayout, fate attenzione a come impostate l'allineamento su TextPaint (). L'utilizzo di TextPaing.setTextAlign (Align.CENTER) mi ha causato problemi poiché telefoni diversi faranno cose diverse con questo.
greg7gkb

2
canvas.getWidth()dovrebbe davvero essere getWidth() - getPaddingLeft() - getPaddingRight(), per tenere conto del riempimento della vista. Inoltre, tieni presente che puoi calcolare lo StaticLayout solo quando il testo o le dimensioni della visualizzazione cambiano e disegnarlo senza costruirne uno nuovo, il che è probabilmente meglio!
Jules

1
@Eenvincible puoi controllare il mio post sul blog qui: skoumal.net/en/android-drawing-multiline-text-on-bitmap
gingo

98

Basta scorrere ogni riga:

int x = 100, y = 100;
for (String line: text.split("\n")) {
      canvas.drawText(line, x, y, mTextPaint);
      y += mTextPaint.descent() - mTextPaint.ascent();
}

C'è un modo decente per calcolare la nuova posizione y? L'aggiunta di un numero apparentemente casuale non mi fa sentire molto a mio agio ...
AgentKnopf

1
Se ritieni che salita + decente sia troppo piccola, puoi aggiungere un fattore di distanza costante o moltiplicare (ad esempio per 1,5 linee) a piacere.
Dave

1
notare che la salita è negativa. In realtà hai bisogno di discesa-salita per ottenere l'altezza
Amir Uval

1
Puoi ottenere le metriche per un carattere selezionato, ad es. Font.measure ("Y")
GregD

11

Ho scritto un esempio completo

inserisci qui la descrizione dell'immagine

colors.xml

  <color name="transparentBlack">#64000000</color>

java class

 public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.amit);
        ImageView imageView = (ImageView)findViewById(R.id.imageView);
        imageView.setImageBitmap(drawTextToBitmap(this, bm, "Name: Kolala\nDate: Dec 23 2016 12:47 PM, \nLocation: 440 Banquets & Restaurents"));

    }

  public Bitmap drawTextToBitmap(Context gContext,
                                   Bitmap bitmap,
                                   String gText) {
        Resources resources = gContext.getResources();
        float scale = resources.getDisplayMetrics().density;

        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 antialised Paint
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

        // text color - #3D3D3D
        paint.setColor(Color.WHITE);
        // text size in pixels
        paint.setTextSize((int) (25 * scale));
        // text shadow
        paint.setShadowLayer(1f, 0f, 1f, Color.WHITE);

        // draw text to the Canvas center
        Rect bounds = new Rect();

        int noOfLines = 0;
        for (String line: gText.split("\n")) {
           noOfLines++;
        }

        paint.getTextBounds(gText, 0, gText.length(), bounds);
        int x = 20;
        int y = (bitmap.getHeight() - bounds.height()*noOfLines);

        Paint mPaint = new Paint();
        mPaint.setColor(getResources().getColor(R.color.transparentBlack));
        int left = 0;
        int top = (bitmap.getHeight() - bounds.height()*(noOfLines+1));
        int right = bitmap.getWidth();
        int bottom = bitmap.getHeight();
        canvas.drawRect(left, top, right, bottom, mPaint);

        for (String line: gText.split("\n")) {
            canvas.drawText(line, x, y, paint);
            y += paint.descent() - paint.ascent();
        }

        return bitmap;
    }
}

4
Perché dovresti usare un ciclo per contare le linee? int noOfLines = gText.split("\n").length
Tomasz

9

Questa è la mia soluzione basata sulla risposta di @ Dave (grazie a proposito ;-))

import android.graphics.Canvas;
import android.graphics.Paint;

public class mdCanvas
{
    private Canvas m_canvas;

    public mdCanvas(Canvas canvas)
    {
        m_canvas = canvas;
    }

    public void drawMultiline(String str, int x, int y, Paint paint)
    {
        for (String line: str.split("\n"))
        {
              m_canvas.drawText(line, x, y, paint);
              y += -paint.ascent() + paint.descent();
        }
    }
}

Ho provato a ereditare Canvas, ma in realtà non te lo consente. Quindi questa è una classe intermedia!


1
Ho provato in questo modo .. tutto funziona bene tranne la mia riga più grande, ultima parola, l'ultimo carattere è mostrato solo a metà. ?
Aada

8

Devo aggiungere qui la mia versione che considera anche la LARGHEZZA DELLA CORSA.

void drawMultiLineText(String str, float x, float y, Paint paint, Canvas canvas) {
   String[] lines = str.split("\n");
   float txtSize = -paint.ascent() + paint.descent();       

   if (paint.getStyle() == Style.FILL_AND_STROKE || paint.getStyle() == Style.STROKE){
      txtSize += paint.getStrokeWidth(); //add stroke width to the text size
   }
   float lineSpace = txtSize * 0.2f;  //default line spacing

   for (int i = 0; i < lines.length; ++i) {
      canvas.drawText(lines[i], x, y + (txtSize + lineSpace) * i, paint);
   }
}

6

Funzionerà. ho provato

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

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


mentre io uso immagine Bitmap = BitmapFactory.decodeResource (mContext.getResources (), R.drawable.transparent_flag); funziona bene, ma se utilizzo un ID di visualizzazione testo invece non funzionerà
DKV

Grazie, ha funzionato esattamente per quello che volevo, ma se puoi aiutarmi a modificare il testo al suo interno o spostarlo in qualsiasi altra posizione, come fa il negozio di foto, grazie in anticipo.
kvadityaaz


5

prova questo

Paint paint1 = new Paint();
paint1.setStyle(Paint.Style.FILL);
paint1.setAntiAlias(true);
paint1.setColor(Color.BLACK);
paint1.setTextSize(15);


TextView tv = new TextView(context);
tv.setTextColor(Color.BLACK);
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
llp.setMargins(5, 2, 0, 0); // llp.setMargins(left, top, right, bottom);
tv.setLayoutParams(llp);
tv.setTextSize(10);
String text="this is good to see you , i am the king of the team";

tv.setText(text);
tv.setDrawingCacheEnabled(true);
tv.measure(MeasureSpec.makeMeasureSpec(canvas.getWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(canvas.getHeight(), MeasureSpec.EXACTLY));
tv.layout(0, 0, tv.getMeasuredWidth(), tv.getMeasuredHeight());
canvas.drawBitmap(tv.getDrawingCache(), 5, 10, paint1);
tv.setDrawingCacheEnabled(false);

6
Penso che questo sia l'esempio perfetto di cosa NON fare in onDraw.
Rupps

@rupps Sì, potrebbe essere eccessivo includere tutto questo in onDraw, ma la risposta non ti dice di farlo. E l'idea è geniale (e ha risolto il mio problema). Screw StaticLayout e String.split!
Rodia

4

Ho riutilizzato la soluzione proposta da GreenBee e ho creato una funzione per disegnare del testo su più righe nei limiti specificati con il "..." alla fine se si è verificato un troncamento:

public static void drawMultiLineEllipsizedText(final Canvas _canvas, final TextPaint _textPaint, final float _left,
            final float _top, final float _right, final float _bottom, final String _text) {
        final float height = _bottom - _top;

        final StaticLayout measuringTextLayout = new StaticLayout(_text, _textPaint, (int) Math.abs(_right - _left),
                Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);

        int line = 0;
        final int totalLineCount = measuringTextLayout.getLineCount();
        for (line = 0; line < totalLineCount; line++) {
            final int lineBottom = measuringTextLayout.getLineBottom(line);
            if (lineBottom > height) {
                break;
            }
        }
        line--;

        if (line < 0) {
            return;
        }

        int lineEnd;
        try {
            lineEnd = measuringTextLayout.getLineEnd(line);
        } catch (Throwable t) {
            lineEnd = _text.length();
        }
        String truncatedText = _text.substring(0, Math.max(0, lineEnd));

        if (truncatedText.length() < 3) {
            return;
        }

        if (truncatedText.length() < _text.length()) {
            truncatedText = truncatedText.substring(0, Math.max(0, truncatedText.length() - 3));
            truncatedText += "...";
        }
        final StaticLayout drawingTextLayout = new StaticLayout(truncatedText, _textPaint, (int) Math.abs(_right
                - _left), Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);

        _canvas.save();
        _canvas.translate(_left, _top);
        drawingTextLayout.draw(_canvas);
        _canvas.restore();
    }

3
Quando il testo viene troncato, il codice potrebbe tagliare anche un'intera parola che si adatta allo spazio. Quindi ecco un piccolo suggerimento per migliorare il tuo codice: sostituisci i tre caratteri "..." con uno solo contenente i tre punti: "..." (il codice & hellip; in HTML). È quindi possibile rimuovere solo un carattere (che spesso è uno spazio) invece di tre e mantenere la parola non tagliata: truncatedText = truncatedText.substring (0, Math.max (0, truncatedText.length () - 1));
Asterius

2

Soluzione senza StaticLayout

//Get post text
    String text = post.getText();

    //Get weight of space character in px
    float spaceWeight = paint.measureText(" ");

    //Start main algorithm of drawing words on canvas
    //Split text to words
    for (String line : text.split(" ")) {
        //If we had empty space just continue
        if (line.equals("")) continue;
        //Get weight of the line
        float lineWeight = paint.measureText(line);
        //If our word(line) doesn't have any '\n' we do next
        if (line.indexOf('\n') == -1) {
            //If word can fit into current line
            if (cnv.getWidth() - pxx - defaultMargin >= lineWeight) {
                //Draw text
                cnv.drawText(line, pxx, pxy, paint);
                //Move start x point to word weight + space weight
                pxx += lineWeight + spaceWeight;
            } else {
                //If word can't fit into current line
                //Move x point to start
                //Move y point to the next line
                pxx = defaultMargin;
                pxy += paint.descent() - paint.ascent();
                //Draw
                cnv.drawText(line, pxx, pxy, paint);
                //Move x point to word weight + space weight
                pxx += lineWeight + spaceWeight;
            }
            //If line contains '\n'
        } else {
            //If '\n' is on the start of the line
            if (line.indexOf('\n') == 0) {
                pxx = defaultMargin;
                pxy += paint.descent() - paint.ascent();
                cnv.drawText(line.replaceAll("\n", ""), pxx, pxy, paint);
                pxx += lineWeight + spaceWeight;
            } else {
                //If '\n' is somewhere in the middle
                //and it also can contain few '\n'
                //Split line to sublines
                String[] subline = line.split("\n");
                for (int i = 0; i < subline.length; i++) {
                    //Get weight of new word
                    lineWeight = paint.measureText(subline[i]);
                    //If it's empty subline that's mean that we have '\n'
                    if (subline[i].equals("")) {
                        pxx = defaultMargin;
                        pxy += paint.descent() - paint.ascent();
                        cnv.drawText(subline[i], pxx, pxy, paint);
                        continue;
                    }
                    //If we have only one word
                    if (subline.length == 1 && i == 0) {
                        if (cnv.getWidth() - pxx >= lineWeight) {
                            cnv.drawText(subline[0], pxx, pxy, paint);
                            pxx = defaultMargin;
                            pxy += paint.descent() - paint.ascent();
                        } else {
                            pxx = defaultMargin;
                            pxy += paint.descent() - paint.ascent();
                            cnv.drawText(subline[0], pxx, pxy, paint);
                            pxx = defaultMargin;
                            pxy += paint.descent() - paint.ascent();
                        }
                        continue;
                    }
                    //If we have set of words separated with '\n'
                    //it is the first word
                    //Make sure we can put it into current line
                    if (i == 0) {
                        if (cnv.getWidth() - pxx >= lineWeight) {
                            cnv.drawText(subline[0], pxx, pxy, paint);
                            pxx = defaultMargin;
                        } else {
                            pxx = defaultMargin;
                            pxy += paint.descent() - paint.ascent();
                            cnv.drawText(subline[0], pxx, pxy, paint);
                            pxx = defaultMargin;
                        }
                    } else {
                        pxx = defaultMargin;
                        pxy += paint.descent() - paint.ascent();
                        cnv.drawText(subline[i], pxx, pxy, paint);
                        pxx += lineWeight + spaceWeight;
                    }
                }

            }
        }
    }

2

Ho lavorato con quello che avevo, che ha già convertito singole linee in tele, e ho elaborato la risposta di Lumis, e ho finito con questo. 1.3 e 1.3f sono intesi come riempimento tra le righe, in relazione alla dimensione del carattere.

public static Bitmap getBitmapFromString(final String text, final String font, int textSize, final int textColor)
{
    String lines[] = text.split("\n");
    textSize = getRelX(textSize);  //a method in my app that adjusts the font size relative to the screen size
    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setTextSize(textSize);
    paint.setColor(textColor);
    paint.setTextAlign(Paint.Align.LEFT);
    Typeface face = Typeface.createFromAsset(GameActivity.getContext().getAssets(),GameActivity.getContext().getString(R.string.font) + font + GameActivity.getContext().getString(R.string.font_ttf));
    paint.setTypeface(face);
    float baseline = -paint.ascent(); // ascent() is negative
    int width = (int) (paint.measureText(text) + 0.5f); // round
    int height = (int) (baseline + paint.descent() + 0.5f);
    Bitmap image = Bitmap.createBitmap(width, (int)(height * 1.3 * lines.length), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(image);
    for (int i = 0; i < lines.length; ++i)
    {
        canvas.drawText(lines[i], 0, baseline + textSize * 1.3f * i, paint);
    }
    return image;
}

0

Ho affrontato un problema simile. ma dovrei restituire il percorso del testo. puoi disegnare questo percorso su Canvas. questo è il mio codice. Uso Break Text. e path.op

           public Path createClipPath(int width, int height) {
            final Path path = new Path();
            if (textView != null) {
                mText = textView.getText().toString();
                mTextPaint = textView.getPaint();
                float text_position_x = 0;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                    text_position_x = findTextBounds(textView).left;

                }
                boolean flag = true;
                int line = 0;
                int startPointer = 0;
                int endPointer = mText.length();

                while (flag) {
                    Path p = new Path();
                    int breakText = mTextPaint.breakText(mText.substring(startPointer), true, width, null);
                    mTextPaint.getTextPath(mText, startPointer, startPointer + breakText, text_position_x,
                            textView.getBaseline() + mTextPaint.getFontSpacing() * line, p);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                        path.op(p, Path.Op.UNION);
                    }
                    endPointer -= breakText;
                    startPointer += breakText;
                    line++;
                    if (endPointer == 0) {
                        flag = false;
                    }
                }

            }
            return path;
        }

e per trovare il testo legato ho usato questa funzione

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
private Rect findTextBounds(TextView textView) {
    // Force measure of text pre-layout.
    textView.measure(0, 0);
    String s = (String) textView.getText();

    // bounds will store the rectangle that will circumscribe the text.
    Rect bounds = new Rect();
    Paint textPaint = textView.getPaint();

    // Get the bounds for the text. Top and bottom are measured from the baseline. Left
    // and right are measured from 0.
    textPaint.getTextBounds(s, 0, s.length(), bounds);
    int baseline = textView.getBaseline();
    bounds.top = baseline + bounds.top;
    bounds.bottom = baseline + bounds.bottom;
    int startPadding = textView.getPaddingStart();
    bounds.left += startPadding;

    // textPaint.getTextBounds() has already computed a value for the width of the text,
    // however, Paint#measureText() gives a more accurate value.
    bounds.right = (int) textPaint.measureText(s, 0, s.length()) + startPadding;
    return bounds;
}


0

Oltre a disegnare testo multilinea, si potrebbe avere difficoltà a ottenere i limiti del testo multilinea (ad esempio per allinearlo sulla tela).
Predefinitopaint.getTextBounds() non funzionerà in questo caso poiché misurerà l'unica linea.

Per comodità, ho creato queste 2 funzioni di estensione: una per disegnare testo multilinea e l'altra per ottenere i limiti del testo.

private val textBoundsRect = Rect()

/**
 * Draws multi-line text on the Canvas with the origin at (x,y), using the specified paint. The origin is interpreted
 * based on the Align setting in the paint.
 *
 * @param text The text to be drawn
 * @param x The x-coordinate of the origin of the text being drawn
 * @param y The y-coordinate of the baseline of the text being drawn
 * @param paint The paint used for the text (e.g. color, size, style)
 */
fun Canvas.drawTextMultiLine(text: String, x: Float, y: Float, paint: Paint) {
    var lineY = y
    for (line in text.split("\n")) {
        lineY += paint.descent().toInt() - paint.ascent().toInt()
        drawText(line, x, lineY, paint)
    }
}

/**
 * Retrieve the text boundary box, taking into account line breaks [\n] and store to [boundsRect].
 *
 * Return in bounds (allocated by the caller [boundsRect] or default mutable [textBoundsRect]) the smallest rectangle that
 * encloses all of the characters, with an implied origin at (0,0).
 *
 * @param text string to measure and return its bounds
 * @param start index of the first char in the string to measure. By default is 0.
 * @param end 1 past the last char in the string to measure. By default is test length.
 * @param boundsRect rect to save bounds. Note, you may not supply it. By default, it will apply values to the mutable [textBoundsRect] and return it.
 * In this case it will be changed by each new this function call.
 */
fun Paint.getTextBoundsMultiLine(
    text: String,
    start: Int = 0,
    end: Int = text.length,
    boundsRect: Rect = textBoundsRect
): Rect {
    getTextBounds(text, start, end, boundsRect)
    val linesCount = text.split("\n").size
    val allLinesHeight = (descent().toInt() - ascent().toInt()) * linesCount
    boundsRect.bottom = boundsRect.top + allLinesHeight
    return boundsRect
}

Ora usarlo è così facile: Per disegnare testo multilinea:

canvas.drawTextMultiLine(text, x, y, yourPaint)

Per misurare il testo:

val bounds = yourPaint.getTextBoundsMultiLine (testo)

In questo caso, misurerà tutto il testo dall'inizio alla fine e con l'utilizzo di default una volta allocato (modificabile) Rect.
Puoi giocare con il passaggio di parametri extra per una maggiore flessibilità.


-1

Il mio esempio con il dimensionamento dinamico del testo e la spaziatura, funziona alla grande per me ...

public Bitmap fontTexture(String string, final Context context) {
    float text_x = 512;
    float text_y = 512;
    final float scale = context.getResources().getDisplayMetrics().density;

    int mThreshold = (int) (THRESHOLD_DIP * scale + 0.5f);

    String[] splited = string.split("\\s+");
    double longest = 0;
    for(String s:splited){
        if (s.length() > longest) {
            longest = s.length();
        }
    }
    if(longest > MAX_STRING_LENGTH) {
        double ratio = (double) MAX_STRING_LENGTH / longest;
        mThreshold = (int) ((THRESHOLD_DIP * ((float) ratio)) * scale + 0.5f);
    }

    Bitmap bitmap = Bitmap.createBitmap(1024, 1024, Bitmap.Config.ARGB_8888);

    Canvas canvas = new Canvas(bitmap);

    Typeface font = Typeface.createFromAsset(context.getAssets(),
            "fonts/dotted_font.ttf");

    TextPaint mTextPaint=new TextPaint();
    mTextPaint.setColor(Color.YELLOW);
    mTextPaint.setTextAlign(Paint.Align.CENTER);
    mTextPaint.setTextSize(mThreshold);
    mTextPaint.setTypeface(font);
    StaticLayout mTextLayout = new StaticLayout(string, mTextPaint, canvas.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);

    canvas.save();

    canvas.translate(text_x, text_y);
    mTextLayout.draw(canvas);
    canvas.restore();


    return bitmap;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.