Android: TextView: rimuovere spaziatura e imbottitura in alto e in basso


208

Quando ho a TextViewcon a \nnel testo, a destra ho due singleLine TextViews, uno sotto l'altro senza spazio tra. Ho impostato quanto segue per tutte TextViewe tre le s.

android:lineSpacingMultiplier="1" 
android:lineSpacingExtra="0pt" 
android:paddingTop="0pt" 
android:paddingBottom="0pt"

La prima riga di sinistra si TextViewallinea perfettamente con quella in alto a destra TextView.

La seconda riga a sinistra TextViewè leggermente più alta della seconda riga in basso a destra TextView.

Sembra che ci sia una sorta di imbottitura nascosta nella parte superiore e inferiore della TextViews. Come posso rimuoverlo?


prova a impostare la gravità di questa visualizzazione di testo su center_vertical
Dawid Hyży il

Ciao George Bailey, hai una soluzione dopo tanto tempo? Ho riscontrato questo problema anche adesso. Puoi darmi la tua soluzione? Grazie.
mmm2006,

1
@ mmm2006, è passato così tanto tempo che non so cosa ho finito per fare. Prova le soluzioni nelle risposte. Se non funziona, fai una nuova domanda.
Bryan Field,

Questo non ha funzionato per me
Marty Miller,

nessuna delle risposte di seguito non ha funzionato per me, puoi aiutarmi
Richa il

Risposte:


521
setIncludeFontPadding (boolean includepad)

o in XMLquesto sarebbe:

android:includeFontPadding="false"

Imposta se TextViewincludere le imbottiture superiore e inferiore extra per fare spazio agli accenti che vanno al di sopra della normale salita e discesa. L'impostazione predefinita è vera.


3
Ma sembra che abbia sempre 1dpun'imbottitura superiore / inferiore, sbaglio? (Uso Developer options -> Show layout bounds)
Autobots

94
includeFontPadding="false"rimuove parte dello spazio, ma non tutto. molto strano.
theblang,

7
Questa può essere un'arma a doppio taglio. includeFontPaddingè ottimo per rimuovere eventuali imbottiture aggiuntive dal carattere stesso ma può causare problemi nelle lingue con ascendenti e discendenti. Se lo fai, mi assicurerei di testare lingue come lo spagnolo e il thai se le supporti.
Elliott

3
Dopo aver impostato il runtime, non sta prendendo il padding superiore ma il padding inferiore ancora lì, anche il padding sinistro e destro? qualche suggerimento?
CoDe

5
Questo non ha funzionato per me. Non capisco cosa mi sto perdendo. Ho ancora spazio indesiderato nella parte inferiore del mio TextView
Marty Miller

41

Condivido il tuo dolore. Ho provato tutte le risposte sopra, incluso ilsetIncludeFontPadding falso, che non ha fatto nulla per me.

La mia soluzione? layout_marginBottom="-3dp"sulTextView ti dà una soluzione per il fondo, BAM!

Sebbene, -3dp su layout_marginTopnon riesca .... ugh.


6
Questo può portare alla fine del testo potenzialmente tagliato
Jason Robinson,

2
Davvero una cattiva idea di usare un margine negativo. Meglio considerare una vista personalizzata e disegnare il testo esattamente come vuoi.
Flynn81

Se patch come questa, dovresti calcolare anche il rapporto tra la dimensione del carattere.
phnghue,

37

Ho cercato molto per la risposta corretta, ma non ho trovato una risposta in grado di rimuovere esattamente tutto il padding dal TextView, ma finalmente dopo aver esaminato il documento ufficiale ho trovato un lavoro per i testi a linea singola

android:includeFontPadding="false"
android:lineSpacingExtra="0dp"

L'aggiunta di queste due righe a TextViewXML farà il lavoro.
Il primo attributo rimuove il riempimento riservato per gli accenti e il secondo attributo rimuove la spaziatura riservata per mantenere lo spazio adeguato tra due righe di testo.

Assicurati di non aggiungere lineSpacingExtra="0dp"TextView su più righe poiché potrebbe rendere goffo l'aspetto


11
l'aggiunta di queste due righe non funziona per me e inoltre non vi è alcun cambiamento
nell'imbottitura

@sunilkushwah, funzionerà sicuramente se lo stai facendo correttamente. Saremo lieti di aiutarti se puoi fornire maggiori dettagli sul tuo problema.
Mohammed Atif,

@sunilkushwah Probabilmente puoi spingerlo su github e condividere il link
Mohammed Atif

@sunilkushwah vedo che stai usando Brandon Font (carattere personalizzato). Puoi provare una volta rimuovendo l' fontPathattributo?
Mohammed Atif,

ho provato questo ma non funziona, Nota: non voglio alcuna imbottitura predefinita in TextView
sunil kushwah

14

Se usi AppCompatTextView(o daAPI 28 poi) puoi usare la combinazione di quei 2 attributi per rimuovere la spaziatura sulla prima riga:

XML

android:firstBaselineToTopHeight="0dp"
android:includeFontPadding="false"

Kotlin

text.firstBaselineToTopHeight = 0
text.includeFontPadding = false

11

Anche questo mi ha infastidito, e la risposta che ho trovato è stata che in realtà c'è spazio aggiuntivo nel font stesso, non in TextView. È piuttosto irritante, proveniente da un background di pubblicazione di documenti, la quantità limitata di controllo che hai con Android sugli elementi tipografici. Consiglio di utilizzare un carattere tipografico personalizzato (come Bitstream Vera Sans, che è concesso in licenza per la ridistribuzione) che potrebbe non avere questo problema. Non sono sicuro, in particolare, se lo faccia o meno.


hai qualche font gratuito a cui indicarmi? Non ho bisogno di alcun margine in alto senza assegnare margini negativi! Grazie!
caveau

11

Puoi provare a usare questo attributo (ConstraintLayout):layout_constraintBaseline_toBaselineOf

Come questo:

app: layout_constraintBaseline_toBaselineOf = "@ + id / textView"

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine


10

Rimuovo la spaziatura nella mia vista personalizzata - NoPaddingTextView.

https://github.com/SenhLinsh/NoPaddingTextView

inserisci qui la descrizione dell'immagine

package com.linsh.nopaddingtextview;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.widget.TextView;

/**
 * Created by Senh Linsh on 17/3/27.
 */

public class NoPaddingTextView extends TextView {

    private int mAdditionalPadding;

    public NoPaddingTextView(Context context) {
        super(context);
        init();
    }


    public NoPaddingTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        setIncludeFontPadding(false);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int yOff = -mAdditionalPadding / 6;
        canvas.translate(0, yOff);
        super.onDraw(canvas);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        getAdditionalPadding();

        int mode = MeasureSpec.getMode(heightMeasureSpec);
        if (mode != MeasureSpec.EXACTLY) {
            int measureHeight = measureHeight(getText().toString(), widthMeasureSpec);

            int height = measureHeight - mAdditionalPadding;
            height += getPaddingTop() + getPaddingBottom();
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    private int measureHeight(String text, int widthMeasureSpec) {
        float textSize = getTextSize();

        TextView textView = new TextView(getContext());
        textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
        textView.setText(text);
        textView.measure(widthMeasureSpec, 0);
        return textView.getMeasuredHeight();
    }

    private int getAdditionalPadding() {
        float textSize = getTextSize();

        TextView textView = new TextView(getContext());
        textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
        textView.setLines(1);
        textView.measure(0, 0);
        int measuredHeight = textView.getMeasuredHeight();
        if (measuredHeight - textSize > 0) {
            mAdditionalPadding = (int) (measuredHeight - textSize);
            Log.v("NoPaddingTextView", "onMeasure: height=" + measuredHeight + " textSize=" + textSize + " mAdditionalPadding=" + mAdditionalPadding);
        }
        return mAdditionalPadding;
    }
}

Questa domanda o risposta è?
Tushar

@Tushar È una risposta.
Linsh

Ok. Potete per favore aggiungere qualche spiegazione con il codice qui.
Tushar

@Tushar Certo, ma è un po 'di più.
Linsh

3
Sebbene questo codice possa risolvere la domanda, inclusa una spiegazione di come e perché questo risolva il problema, contribuirebbe davvero a migliorare la qualità del tuo post (e ottenere voti positivi). Ricorda che stai rispondendo alla domanda per i lettori in futuro, non solo per la persona che chiede ora! Modifica la tua risposta per aggiungere spiegazioni e fornire un'indicazione di quali limitazioni e ipotesi si applicano.
Makyen

3
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/baselineImage"
        android:includeFontPadding="false" />

    <ImageView
        android:id="@+id/baselineImage"
        android:layout_width="1dp"
        android:layout_height="1dp"
        android:baselineAlignBottom="true"
        android:layout_alignParentBottom="true" />

    <!-- This view will be exactly 10dp below the baseline of textView -->
    <View
        android:id="@+id/view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_below="@+id/baselineImage" />

</RelativeLayout>

Con un ulteriore ImageView possiamo impostare TextView in modo che sia allineato alla base con ImageView e impostare android:baselineAlignBottomImageView su true, il che renderà la base di ImageView in basso. Altre viste possono allinearsi utilizzando la parte inferiore di ImageView, che a sua volta è uguale alla linea di base di TextView.

Questo tuttavia risolve solo il fondo dell'imbottitura, non quello superiore.


perfetto per la mia situazione, molto meglio della rimozione dell'imbottitura dei caratteri. +1
Bawa,

3

Penso che questo problema possa essere risolto in questo modo:

 <TextView
        android:id="@+id/leftText"
        android:includeFontPadding="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="30dp"
        android:text="Hello World!\nhello world" />

 <TextView
        android:id="@+id/rightUpperText"
        android:includeFontPadding="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/leftText"
        android:layout_alignTop="@+id/leftText"
        android:textSize="30dp"
        android:text="Hello World!" />

 <TextView
        android:id="@+id/rightLowerText"
        android:includeFontPadding="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/leftText"
        android:layout_below="@+id/rightUpperText"
        android:textSize="30dp"
        android:text="hello world" />

Questi sono i risultati:

Screenshot-1

Screenshot-3

Sebbene la linea di caratteri speciali in rightLowerText sembri un po 'più alta della seconda riga di leftText, le loro linee di base sono ancora allineate.


includeFontPadding = "false" era esattamente ciò di cui avevo bisogno! Grazie.
Hman,

3

Poiché il mio requisito è quello di sostituire il textView esistente findViewById(getResources().getIdentifier("xxx", "id", "android"));, quindi non posso semplicemente provare onDraw()ad un'altra risposta.

Ma ho appena capito i passaggi corretti per risolvere il mio problema, ecco il risultato finale da Inspector layout:

inserisci qui la descrizione dell'immagine

Dal momento che quello che volevo è semplicemente rimuovere gli spazi superiori, quindi non devo scegliere altri caratteri per rimuovere gli spazi inferiori.

Ecco il codice critico per risolverlo:

Typeface mfont = Typeface.createFromAsset(getResources().getAssets(), "fonts/myCustomFont.otf");
myTextView.setTypeface(mfont);

myTextView.setPadding(0, 0, 0, 0);

myTextView.setIncludeFontPadding(false);

La prima chiave è impostare il carattere personalizzato "fonts / myCustomFont.otf" che ha lo spazio in basso ma non in alto, puoi facilmente capirlo aprendo il file otf e fai clic su qualsiasi carattere in Android Studio:

inserisci qui la descrizione dell'immagine

Come puoi vedere, il cursore in basso ha una spaziatura aggiuntiva ma non in alto, quindi ha risolto il mio problema.

La seconda chiave è che non puoi semplicemente saltare alcun codice , altrimenti potrebbe non funzionare. Questo è il motivo per cui puoi trovare alcune persone che commentano che una risposta sta funzionando e altre che commentano che non funziona.

Illustriamo cosa accadrà se ne rimuoverò uno.

Senza setTypeface(mfont);:

inserisci qui la descrizione dell'immagine

Senza setPadding(0, 0, 0, 0);:

inserisci qui la descrizione dell'immagine

Senza setIncludeFontPadding(false);:

inserisci qui la descrizione dell'immagine

Senza 3 di essi (ovvero l'originale):

inserisci qui la descrizione dell'immagine



3

XML aggiornato

android:fontFamily="monospace"
android:includeFontPadding="false"

Ciao, benvenuto in Stack Overflow! Quando rispondi a una domanda dovresti includere una sorta di spiegazione, come ciò che l'autore ha fatto di sbagliato e cosa hai fatto per risolverlo. Te lo dico perché la tua risposta è stata contrassegnata come di bassa qualità ed è attualmente in fase di revisione. Puoi modificare la tua risposta facendo clic sul pulsante "Modifica".
Federico Grandi,

In realtà cambiare Android: fontFamily non è necessario se hai già il carattere corretto. Fondamentalmente Android: includeFontPadding è l'unica cosa necessaria ed è stato menzionato nelle risposte precedenti dal thread.
Darek Deoniziak,

@DarekDeoniziak Alcuni caratteri hanno spazi
SJJ

2

Metodo semplice ha funzionato:

setSingleLine();
setIncludeFontPadding(false);

Se non ha funzionato, prova ad aggiungere questo sopra quel codice:

setLineSpacing(0f,0f);
// and set padding and margin to 0

Se hai bisogno di più righe, forse dovrai calcolare esattamente l'altezza dell'imbottitura in alto e in basso tramite TextView a linea singola temporanea (prima e dopo la rimozione dell'imbottitura), quindi applica il risultato di riduzione dell'altezza con imbottitura negativa o un layout Ghost con traslazione Y. lol


0

Potresti provare ad allineare la parte inferiore della vista di testo a sinistra con la parte inferiore della seconda vista di testo a destra.


Ma poi la linea superiore non si allinea. E in realtà non mi interessa che si allineino tanto quanto vorrei davvero rimuovere la spaziatura.
Bryan Field,

0

Per quanto ne so, questo è inerente alla maggior parte dei widget e la quantità di "riempimento" differisce tra i produttori di telefoni. Questa imbottitura è davvero uno spazio bianco tra il bordo dell'immagine e l'immagine nel file immagine 9 patch.

Ad esempio sul mio Droid X, i widget di spinner ottengono uno spazio bianco extra rispetto ai pulsanti, il che lo rende imbarazzante quando hai uno spinner in linea con un pulsante, ma sul telefono di mia moglie la stessa applicazione non ha lo stesso problema ed è fantastica!

L'unico suggerimento che avrei è di creare i tuoi 9 file patch e usarli nella tua applicazione.

Ahhh i dolori che sono Android.

Modificato: chiarire l'imbottitura rispetto allo spazio bianco.


0

Questo trucco ha funzionato per me (per min-sdk> = 18 ).

Ho usato android:includeFontPadding="false"e un margine negativo come android:layout_marginTop="-11dp"e mettere il mio TextViewdentro un FrameLayout( o qualsiasi ViewGroup ... )

inserisci qui la descrizione dell'immagine

e infine codici di esempio:

<LinearLayout
    android:layout_width="60dp"
    android:layout_height="wrap_content"
    >

    <TextView
        style="@style/MyTextViews.Bold"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/yellow"
        android:textSize="48sp"
        android:layout_marginTop="-11dp"
        android:includeFontPadding="false"
        tools:text="1"/>
</LinearLayout>

1
Questo trucco potrebbe non funzionare con caratteri, dimensioni o layout diversi.
Adil Soomro,

-1

Guarda questo:

Allineare ImageView con EditText in orizzontale

Sembra che l'immagine di sfondo di EditText abbia alcuni pixel trasparenti che aggiungono anche il riempimento.

Una soluzione è quella di cambiare lo sfondo predefinito di EditText in qualcos'altro (o niente, ma probabilmente non è accettabile uno sfondo per un EditText). Questo può essere fatto impostando android: l'attributo XML in background.

android:background="@drawable/myEditBackground"


-5

Usa questo nel tuo XML ImageView

Android: adjustViewBounds = "true"


Per favore, aggiungi qualche spiegazione a riguardo
Nico Haase,

pensavo che questo dovesse essere compreso. Posso essere utilizzato solo in XML.
Anshul Rawat il
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.