web-dev-qa-db-fra.com

Android: TextView: Suppression de l'espacement et du remplissage en haut et en bas

Quand j'ai un TextView avec un \n dans le texte, à droite, j'ai deux singleLineTextViews, l'un en dessous de l'autre, sans espacement. J'ai défini ce qui suit pour les trois TextViews.

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

La première ligne de gauche TextView s'aligne parfaitement avec le coin supérieur droit TextView.

La deuxième ligne de gauche TextView est un peu plus haute que la deuxième ligne de droite inférieure TextView.

Il semble qu'il y ait une sorte de bourrage caché en haut et en bas du TextViews. Comment puis-je enlever ça?

175
Bryan Field
setIncludeFontPadding (boolean includepad)

ou dans XML ce serait:

Android:includeFontPadding="false"

Définissez si la variable TextView comprend un rembourrage supérieur et inférieur supplémentaire afin de laisser la place aux accents qui dépassent la montée et la descente normales. Le défaut est vrai.

456
user634545

Je ressens ta douleur. J'ai essayé toutes les réponses ci-dessus, y compris le setIncludeFontPadding à faux, ce qui n'a fait rien pour moi.

Ma solution? layout_marginBottom="-3dp" sur le TextView vous donne une solution pour le fond, BAM!

Bien que, -3dp sur layout_marginTop échoue .... euh.

39
hunterp

Je cherchais beaucoup de réponses correctes, mais je ne trouvais pas de réponse qui puisse supprimer exactement tout le remplissage du TextView, mais finalement, après avoir parcouru le document officiel obtenu un travail pour Textes sur une seule ligne

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

Ajouter ces deux lignes à TextView xml fera le travail.
Le premier attribut supprime le remplissage réservé aux accents et le deuxième attribut supprime l'espacement réservé au maintien d'un espace correct entre deux lignes de texte.

Assurez-vous de ne pas ajouter lineSpacingExtra="0dp" dans TextView multiligne car cela pourrait rendre l’apparence maladroite.

32
Mohammed Atif

Cela m'a agacé aussi, et la réponse que j'ai trouvée est qu'il y a réellement de l'espace supplémentaire dans la police elle-même, pas dans TextView. C’est plutôt irritant, du point de vue de la publication de documents, du contrôle limité que vous avez avec Android sur les éléments typographiques. Je vous recommande d'utiliser une police de caractères personnalisée (telle que Bitstream Vera Sans, qui est autorisée à la redistribution) qui n'a peut-être pas ce problème. Je ne suis toutefois pas certain que ce soit le cas ou non.

9
kcoppock

Je supprime l'espacement dans ma vue personnalisée - NoPaddingTextView.

https://github.com/SenhLinsh/NoPaddingTextView

enter image description here

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

Avec un ImageView supplémentaire, nous pouvons définir le TextView sur la ligne de base alignée avec le ImageView et définir le Android:baselineAlignBottom du ImageView sur true, ce qui ramènera la ligne de base de ImageView au bas. D'autres vues peuvent s'aligner à l'aide du bas de ImageView, qui est identique à la ligne de base de TextView.

Ceci ne fixe toutefois que le bas du rembourrage et non le haut.

3
Viven

Étant donné que mon exigence est de remplacer le textView existant à partir de findViewById(getResources().getIdentifier("xxx", "id", "Android"));, je ne peux donc pas simplement essayer onDraw() d'une autre réponse.

Mais je viens de comprendre les étapes correctes pour résoudre mon problème, voici le résultat final de l'inspecteur de disposition:

enter image description here

Étant donné que je voulais simplement supprimer les espaces en haut, je n'ai donc pas à choisir une autre police pour supprimer les espaces en bas.

Voici le code critique pour le réparer:

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

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

myTextView.setIncludeFontPadding(false);

La première clé est la police personnalisée "fonts/myCustomFont.otf" qui a l'espace en bas mais pas en haut, vous pouvez facilement le savoir en ouvrant le fichier otf et en cliquant sur une police dans Android Studio:

enter image description here

Comme vous pouvez le constater, le curseur situé en bas a un espacement supplémentaire, mais pas en haut, il a donc résolu mon problème.

La deuxième clé est , vous ne pouvez simplement ignorer aucun code , sinon cela pourrait ne pas fonctionner. C’est la raison pour laquelle certaines personnes ont fait savoir qu’une réponse fonctionnait et que d’autres ont fait remarquer que cela ne fonctionnait pas.

Illustrons ce qui se passera si j'en enlève un.

Sans setTypeface(mfont);:

enter image description here

Sans setPadding(0, 0, 0, 0);:

enter image description here

Sans setIncludeFontPadding(false);:

enter image description here

Sans 3 d'entre eux (c'est-à-dire l'original):

enter image description here

3
林果皞

Je pense que ce problème peut être résolu de cette façon:

 <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" />

Ce sont les résultats:

ScreenShot-1

ScreenShot-

Bien que la ligne de caractères spéciaux dans rightLowerText semble un peu plus haute que la deuxième ligne de leftText, leurs lignes de base sont toujours alignées.

3
Wei Wei

Si vous utilisez AppCompatTextView (ou à partir de API 27.), Vous pouvez utiliser la combinaison de ces 2 attributs pour supprimer l'espacement sur la première ligne:

XML

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

Kotlin

text.firstBaselineToTopHeight = 0
text.includeFontPadding = false
2
Mario Lenci

Méthode simple travaillée:

setSingleLine();
setIncludeFontPadding(false);

Si cela n'a pas fonctionné, essayez d'ajouter ceci au-dessus de ce code:

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

Si vous avez besoin de plusieurs lignes, vous devrez peut-être calculer exactement la hauteur du remplissage en haut et en bas via une ligne temporaire TextView (avant et après suppression du remplissage), puis appliquer le résultat de diminution de la hauteur avec un remplissage négatif ou une mise en page Ghost avec translate Y. Lol

2
phnghue

Vous pouvez essayer d'utiliser cet attribut (ConstraintLayout): layout_constraintBaseline_toBaselineOf

Comme ça:

app: layout_constraintBaseline_toBaselineOf = "@ + id/textView"

enter image description here

enter image description here

2
windplume

La seule chose qui a fonctionné est

Android:lineSpacingExtra="-8dp"
1
Antonis Radz

Vous voudrez peut-être essayer d’aligner le bas de la vue de gauche avec le bas de la deuxième vue de droite.

0
Jems

Simplement utiliser

Android:padding="0dp"
0
Juan Bernal

À ma connaissance, cela est inhérent à la plupart des widgets et la quantité de "rembourrage" diffère selon les fabricants de téléphones. Ce remplissage est vraiment un espace blanc entre la bordure de l'image et l'image dans le fichier image de 9 patchs.

Par exemple, sur mon Droid X, les widgets Spinner ont plus d'espace que les boutons, ce qui le rend bizarre lorsque vous avez un spinner en ligne avec un bouton. Pourtant, sur le téléphone de ma femme, la même application n'a pas le même problème et a fière allure!

La seule suggestion que je puisse faire est de créer vos propres 9 fichiers de correctifs et de les utiliser dans votre application.

Ahhh les douleurs qui sont Android.

Modifié: clarifiez le remplissage par rapport aux espaces.

0
user432209