Skip to content

Come viene utilizzato StaticLayout in Android?

Comprendi bene il codice prima di usarlo nel tuo lavoro, se hai qualcosa da contribuire puoi lasciarlo nella sezione dei commenti.

Soluzione:

StaticLayout (simile a DynamicLayout e BoringLayout) viene utilizzato per impaginare e disegnare il testo su una tela. Viene comunemente utilizzato per i seguenti compiti:

  • Misurare le dimensioni di un testo multilinea dopo averlo impaginato.
  • Disegnare testo su un'immagine bitmap.
  • Creare una vista personalizzata che gestisca il proprio layout di testo (invece di creare una vista composita con una vista incorporata). TextView). TextView utilizza una vista StaticLayout internamente.

Misurazione della dimensione del testo

Linea singola

Se si dispone di una sola riga di testo, è possibile misurarla con Paint o TextPaint.

String text = "This is some text."

TextPaint myTextPaint = new TextPaint();
mTextPaint.setAntiAlias(true);
mTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density);
mTextPaint.setColor(0xFF000000);

float width = mTextPaint.measureText(text);
float height = -mTextPaint.ascent() + mTextPaint.descent();

Multilinea

Tuttavia, se c'è il line wrapping e si ha bisogno dell'altezza, è meglio usare un elemento StaticLayout. Si fornisce la larghezza e poi si può ottenere l'altezza dall'elemento StaticLayout.

String text = "This is some text. This is some text. This is some text. This is some text. This is some text. This is some text.";

TextPaint myTextPaint = new TextPaint();
myTextPaint.setAntiAlias(true);
myTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density);
myTextPaint.setColor(0xFF000000);

int width = 200;
Layout.Alignment alignment = Layout.Alignment.ALIGN_NORMAL;
float spacingMultiplier = 1;
float spacingAddition = 0;
boolean includePadding = false;

StaticLayout myStaticLayout = new StaticLayout(text, myTextPaint, width, alignment, spacingMultiplier, spacingAddition, includePadding);

float height = myStaticLayout.getHeight(); 

Nuova API

Se si vuole usare la più recente StaticLayout.Builder (disponibile a partire dall'API 23), si può ottenere il layout in questo modo:

StaticLayout.Builder builder = StaticLayout.Builder.obtain(text, 0, text.length(), myTextPaint, width);
StaticLayout myStaticLayout = builder.build();

Si possono aggiungere impostazioni aggiuntive usando la notazione a punti:

StaticLayout.Builder builder = StaticLayout.Builder.obtain(text, 0, text.length(), myTextPaint, width)
        .setAlignment(Layout.Alignment.ALIGN_NORMAL)
        .setLineSpacing(spacingAddition, spacingMultiplier)
        .setIncludePad(includePadding)
        .setMaxLines(5);
StaticLayout myStaticLayout = builder.build();

Scrittura di testo su un'immagine

Potrei approfondire l'argomento in futuro, ma per ora si veda questo post per un esempio di metodo che usa StaticLayout e restituisce una bitmap.

Creare una vista personalizzata per la gestione del testo

Ecco un esempio di vista personalizzata che utilizza un oggetto StaticLayout. Si comporta come un semplice TextView. Quando il testo è troppo lungo per essere visualizzato sullo schermo, viene automaticamente allineato e aumenta la sua altezza.

enter image description here

Codice

MyView.java

public class MyView extends View {

    String mText = "This is some text.";
    TextPaint mTextPaint;
    StaticLayout mStaticLayout;

    // use this constructor if creating MyView programmatically
    public MyView(Context context) {
        super(context);
        initLabelView();
    }

    // this constructor is used when created from xml
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initLabelView();
    }

    private void initLabelView() {
        mTextPaint = new TextPaint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density);
        mTextPaint.setColor(0xFF000000);

        // default to a single line of text
        int width = (int) mTextPaint.measureText(mText);
        mStaticLayout = new StaticLayout(mText, mTextPaint, (int) width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0, false);

        // New API alternate
        //
        // StaticLayout.Builder builder = StaticLayout.Builder.obtain(mText, 0, mText.length(), mTextPaint, width)
        //        .setAlignment(Layout.Alignment.ALIGN_NORMAL)
        //        .setLineSpacing(0, 1) // add, multiplier
        //        .setIncludePad(false);
        // mStaticLayout = builder.build();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // Tell the parent layout how big this view would like to be
        // but still respect any requirements (measure specs) that are passed down.

        // determine the width
        int width;
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthRequirement = MeasureSpec.getSize(widthMeasureSpec);
        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthRequirement;
        } else {
            width = mStaticLayout.getWidth() + getPaddingLeft() + getPaddingRight();
            if (widthMode == MeasureSpec.AT_MOST) {
                if (width > widthRequirement) {
                    width = widthRequirement;
                    // too long for a single line so relayout as multiline
                    mStaticLayout = new StaticLayout(mText, mTextPaint, width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0, false);
                }
            }
        }

        // determine the height
        int height;
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightRequirement = MeasureSpec.getSize(heightMeasureSpec);
        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightRequirement;
        } else {
            height = mStaticLayout.getHeight() + getPaddingTop() + getPaddingBottom();
            if (heightMode == MeasureSpec.AT_MOST) {
                height = Math.min(height, heightRequirement);
            }
        }

        // Required call: set width and height
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // do as little as possible inside onDraw to improve performance

        // draw the text on the canvas after adjusting for padding
        canvas.save();
        canvas.translate(getPaddingLeft(), getPaddingTop());
        mStaticLayout.draw(canvas);
        canvas.restore();
    }
}

activity_main.xml




    

Note

  • Questo, questo e questo sono stati utili per imparare a creare una vista personalizzata per la gestione del testo.

  • Vedere Creazione di una classe di vista se si desidera aggiungere attributi personalizzati che possono essere impostati da codice o xml.

Ecco la mia spiegazione per disegnare testo multilinea su tela.

Dichiarare l'oggetto Paint. Utilizzare TextPaint, che è un'estensione di Paint.

TextPaint textPaint;

Inizializzare l'oggetto Paint. Impostare il proprio colore, le dimensioni, ecc.

textPaint = new TextPaint();
textPaint.setAntiAlias(true);
textPaint.setTextSize(16 * getResources().getDisplayMetrics().density);
textPaint.setColor(Color.YELLOW);

Aggiungere la funzione getTextHeight

private float getTextHeight(String text, Paint paint) {
    Rect rect = new Rect();
    paint.getTextBounds(text, 0, text.length(), rect);
    return rect.height();
}

Nella funzione onDraw inserire le seguenti righe come questa

@Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    String text = "This is a lengthy text. We have to render this properly. If layout mess users review will mess. Is that so ? ";

    Rect bounds = canvas.getClipBounds();

    StaticLayout sl = new StaticLayout(text, textPaint, bounds.width(),
            Layout.Alignment.ALIGN_CENTER, 1, 1, true);

    canvas.save();

    //calculate X and Y coordinates - In this case we want to draw the text in the
    //center of canvas so we calculate
    //text height and number of lines to move Y coordinate to center.
    float textHeight = getTextHeight(text, textPaint);
    int numberOfTextLines = sl.getLineCount();
    float textYCoordinate = bounds.exactCenterY() -
            ((numberOfTextLines * textHeight) / 2);

    //text will be drawn from left
    float textXCoordinate = bounds.left;

    canvas.translate(textXCoordinate, textYCoordinate);

    //draws static layout on canvas
    sl.draw(canvas);
    canvas.restore();
}

La cortesia va al post di KOC

Commenti e valutazioni della guida

Se hai qualche esitazione e capacità di promuovere la nostra sezione, puoi scrivere una cronaca e la osserveremo volentieri.



Utilizzate il nostro motore di ricerca

Ricerca
Generic filters

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.