Android: TextView: Entfernen Sie Abstände und Polsterungen oben und unten

206

Wenn ich ein TextViewmit einem \nim Text habe, habe ich rechts zwei singleLine TextViews untereinander ohne Abstand dazwischen. Ich habe für alle drei TextViews Folgendes eingestellt .

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

Die erste Zeile links TextViewstimmt perfekt mit der oberen rechten überein TextView.

Die zweite Zeile links TextViewist etwas höher als die zweite Zeile unten rechts TextView.

Es scheint, dass es eine Art versteckte Polsterung oben und unten am TextViews gibt. Wie kann ich das entfernen?

Bryan Field
quelle
Versuchen Sie, die Schwerkraft dieser Textansicht auf center_vertical zu setzen
Dawid Hy 6y
Hallo George Bailey, haben Sie nach so langer Zeit eine Lösung? Ich stoße jetzt auch auf dieses Problem. Können Sie mir Ihre Lösung geben? Vielen Dank.
mmm2006
1
@ mmm2006, Schon so lange weiß ich nicht, was ich letztendlich gemacht habe. Probieren Sie die Lösungen in den Antworten aus. Wenn das nicht funktioniert, stellen Sie eine neue Frage.
Bryan Field
Das hat bei mir nicht funktioniert
Marty Miller
Eine der folgenden Antworten hat bei mir nicht funktioniert. Können Sie mir helfen?
Richa

Antworten:

520
setIncludeFontPadding (boolean includepad)

oder in XMLdiesem wäre:

android:includeFontPadding="false"

Stellen Sie ein, ob die TextViewzusätzliche obere und untere Polsterung Platz für Akzente bietet, die über den normalen Auf- und Abstieg hinausgehen. Der Standardwert ist true.

user634545
quelle
3
Aber es scheint immer eine 1dpobere / untere Polsterung zu haben, irre ich mich? (Ich benutze Developer options -> Show layout bounds)
Autobots
94
includeFontPadding="false"entfernt zwar einen Teil des Speicherplatzes, aber nicht den gesamten. sehr eigenartig.
Theblang
7
Dies kann ein zweischneidiges Schwert sein. includeFontPaddingeignet sich hervorragend zum Entfernen zusätzlicher Auffüllungen aus der Schriftart selbst, kann jedoch Probleme in Sprachen mit Auf- und Abwärtsbewegungen verursachen. Ich würde sicherstellen, dass Sie Sprachen wie Spanisch und Thailändisch testen, wenn Sie dies unterstützen.
Elliott
3
Nach dem Einstellen der Laufzeit wird nicht die obere, sondern die untere Polsterung benötigt, auch die linke und rechte Polsterung? irgendein Vorschlag?
CoDe
5
Das hat bei mir nicht funktioniert. Ich verstehe nicht, was mir fehlt. Ich habe immer noch unerwünschten Platz am unteren Rand meiner TextView
Marty Miller
41

Ich fühle deinen Schmerz. Ich habe jede Antwort oben ausprobiert, einschließlich der setIncludeFontPaddingzu falschen, die nichts für mich getan hat.

Meine Lösung? layout_marginBottom="-3dp"auf der TextViewgibt Ihnen eine Lösung für den Boden, BAM!

Obwohl -3dp on layout_marginTopfehlschlägt .... ugh.

Hunterp
quelle
6
Dies kann dazu führen, dass der untere Teil des Textes möglicherweise abgeschnitten wird
Jason Robinson
2
Wirklich schlechte Idee, negative Marge zu verwenden. Betrachten Sie besser eine benutzerdefinierte Ansicht und zeichnen Sie den Text genau so, wie Sie möchten.
Flynn81
Bei einem Patch wie diesem sollten Sie auch das Verhältnis der Schriftgröße berechnen.
phnghue
37

Ich habe viel nach der richtigen Antwort gesucht, aber keine, wo ich eine Antwort finden konnte, die genau die gesamte Polsterung aus der entfernen konnte TextView, aber schließlich, nachdem ich das offizielle Dokument durchgesehen hatte, bekam ich eine Lösung für einzeilige Texte

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

Das Hinzufügen dieser beiden Zeilen zu TextViewXML erledigt die Arbeit.
Das erste Attribut entfernt den für Akzente reservierten Abstand und das zweite Attribut entfernt den reservierten Abstand, um den richtigen Abstand zwischen zwei Textzeilen aufrechtzuerhalten.

lineSpacingExtra="0dp"Stellen Sie sicher, dass Sie keine mehrzeilige Textansicht hinzufügen, da dies das Erscheinungsbild möglicherweise ungeschickt macht

Mohammed Atif
quelle
11
Das Hinzufügen dieser beiden Zeilen funktioniert bei mir nicht und es gibt auch keine Änderung in der Polsterung
Sunil Kushwah
@ Sunilkushwah, es wird definitiv funktionieren, wenn Sie es richtig machen. Wir helfen Ihnen gerne weiter, wenn Sie weitere Details zu Ihrem Problem angeben können.
Mohammed Atif
@ Sunilkushwah Sie können es wahrscheinlich auf Github schieben und den Link teilen
Mohammed Atif
@sunilkushwah Ich sehe, dass Sie Brandon Font (Custom Font) verwenden. Können Sie es einmal versuchen, indem Sie das fontPathAttribut entfernen ?
Mohammed Atif
Ich habe es versucht, aber es funktioniert nicht. Hinweis: Ich möchte keine Standardauffüllung in TextView
Sunil Kushwah
13

Wenn Sie AppCompatTextView(oder ab API 28) verwenden, können Sie die Kombination dieser beiden Attribute verwenden, um den Abstand in der ersten Zeile zu entfernen:

XML

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

Kotlin

text.firstBaselineToTopHeight = 0
text.includeFontPadding = false
Mario Lenci
quelle
11

Das ärgerte mich auch und die Antwort, die ich fand, war, dass tatsächlich zusätzlicher Platz in der Schriftart selbst vorhanden ist, nicht in der Textansicht. Aufgrund des Hintergrunds der Dokumentveröffentlichung ist es ziemlich irritierend, wie wenig Kontrolle Sie mit Android über typografische Elemente haben. Ich würde empfehlen, eine benutzerdefinierte Schriftart zu verwenden (z. B. Bitstream Vera Sans, die für die Weiterverteilung lizenziert ist), bei der dieses Problem möglicherweise nicht auftritt. Ich bin mir jedoch nicht sicher, ob dies der Fall ist oder nicht.

Kevin Coppock
quelle
Haben Sie eine kostenlose Schriftart, auf die Sie mich verweisen können? Ich muss keinen Rand oben haben, ohne negative Ränder zuzuweisen! Danke dir!
Gewölbe
11

Sie können versuchen, dieses Attribut (ConstraintLayout) zu verwenden:layout_constraintBaseline_toBaselineOf

So was:

App: layout_constraintBaseline_toBaselineOf = "@ + id / textView"

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Windfahne
quelle
10

Ich entferne den Abstand in meiner benutzerdefinierten Ansicht - NoPaddingTextView.

https://github.com/SenhLinsh/NoPaddingTextView

Geben Sie hier die Bildbeschreibung ein

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;
    }
}
Linsh
quelle
Ist das eine Frage oder Antwort?
Tushar
@ Tushar Es ist eine Antwort.
Linsh
OK. Können Sie bitte hier eine Erklärung mit Code hinzufügen?
Tushar
@ Tushar Sicher, aber es ist ein bisschen mehr.
Linsh
3
Während dieser Code die Frage lösen kann, würde eine Erklärung, wie und warum dies das Problem löst, wirklich dazu beitragen, die Qualität Ihres Beitrags zu verbessern (und Up-Votes zu erhalten). Denken Sie daran, dass Sie in Zukunft die Frage für die Leser beantworten, nicht nur für die Person, die jetzt fragt! Bitte bearbeiten Sie Ihre Antwort, um eine Erklärung hinzuzufügen, und geben Sie an, welche Einschränkungen und Annahmen gelten.
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>

Mit einer zusätzlichen ImageView können wir die TextView so einstellen, dass sie an der ImageView ausgerichtet ist, und die festlegen android:baselineAlignBottom auf der ImageView auf true setzen, wodurch die Grundlinie von ImageView nach unten verschoben wird. Andere Ansichten können sich am unteren Rand der ImageView ausrichten, was der Grundlinie der TextView entspricht.

Dies fixiert jedoch nur die Polsterung unten, nicht die Oberseite.

Viven
quelle
Perfekt für meine Situation, viel besser als das Entfernen von Schriftauffüllungen. +1
Bawa
3

Ich denke, dieses Problem kann folgendermaßen gelöst werden:

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

Das sind die Ergebnisse:

Screenshot-1

Screenshot-3

Obwohl die Zeile der Sonderzeichen in rightLowerText etwas höher aussieht als die zweite Zeile von leftText, sind ihre Basislinien weiterhin ausgerichtet.

Wei Wei
quelle
includeFontPadding = "false" war genau das, was ich brauchte! Vielen Dank.
hman
3

Da meine Anforderung darin besteht, die vorhandene textView zu überschreiben findViewById(getResources().getIdentifier("xxx", "id", "android"));, kann ich es nicht einfach versuchenonDraw() andere Antwort .

Aber ich finde nur die richtigen Schritte heraus, um mein Problem zu beheben. Hier ist das Endergebnis von Layout Inspector:

Geben Sie hier die Bildbeschreibung ein

Da ich nur die oberen Leerzeichen entfernen wollte, muss ich keine andere Schriftart auswählen, um die unteren Leerzeichen zu entfernen.

Hier ist der kritische Code, um das Problem zu beheben:

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

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

myTextView.setIncludeFontPadding(false);

Der erste Schlüssel ist die benutzerdefinierte Schriftart "fonts / myCustomFont.otf", die den Platz unten, aber nicht oben hat. Sie können dies leicht herausfinden, indem Sie die otf-Datei öffnen und auf eine beliebige Schriftart in Android Studio klicken:

Geben Sie hier die Bildbeschreibung ein

Wie Sie sehen können, hat der Cursor unten einen zusätzlichen Abstand, aber nicht oben, sodass mein Problem behoben wurde.

Der zweite Schlüssel ist, dass Sie den Code nicht einfach überspringen können , da er sonst möglicherweise nicht funktioniert. Das ist der Grund, warum einige Leute kommentieren, dass eine Antwort funktioniert, und andere kommentieren, dass sie nicht funktioniert.

Lassen Sie uns veranschaulichen, was passieren wird, wenn ich einen von ihnen entferne.

Ohne setTypeface(mfont);:

Geben Sie hier die Bildbeschreibung ein

Ohne setPadding(0, 0, 0, 0);:

Geben Sie hier die Bildbeschreibung ein

Ohne setIncludeFontPadding(false);:

Geben Sie hier die Bildbeschreibung ein

Ohne 3 von ihnen (dh das Original):

Geben Sie hier die Bildbeschreibung ein

Obst
quelle
3

Das einzige was funktioniert hat ist

android:lineSpacingExtra="-8dp"
Antonis Radz
quelle
2

Einfache Methode funktioniert:

setSingleLine();
setIncludeFontPadding(false);

Wenn es nicht funktioniert hat, versuchen Sie, dies über dem Code hinzuzufügen:

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

Wenn Sie mehrere Zeilen benötigen, müssen Sie möglicherweise die Höhe des Auffüllens oben und unten über die temporäre TextView-Zeile (vor und nach dem Entfernen des Auffüllens) genau berechnen und dann das Ergebnis zum Verringern der Höhe mit negativem Auffüllen oder ein Ghost-Layout mit translate Y anwenden. Lol

phnghue
quelle
1

XML aktualisiert

android:fontFamily="monospace"
android:includeFontPadding="false"
SJJ
quelle
Hallo, willkommen bei Stack Overflow! Wenn Sie eine Frage beantworten, sollten Sie eine Erklärung hinzufügen, z. B. was der Autor falsch gemacht hat und was Sie getan haben, um sie zu beheben. Ich sage Ihnen dies, weil Ihre Antwort als minderwertig gekennzeichnet wurde und derzeit überprüft wird. Sie können Ihre Antwort bearbeiten , indem Sie auf die Schaltfläche "Bearbeiten" klicken.
Federico Grandi
Android tatsächlich ändern: fontFamily ist nicht erforderlich, wenn Sie bereits die richtige Schriftart haben. Grundsätzlich android: includeFontPadding ist das einzige, was notwendig ist und es wurde in früheren Antworten aus dem Thread erwähnt.
Darek Deoniziak
@DarekDeoniziak Einige Schriftarten haben Leerzeichen
SJJ
0

Möglicherweise möchten Sie versuchen, den unteren Rand der linken Textansicht am unteren Rand der zweiten rechten Textansicht auszurichten.

Jems
quelle
Aber dann würde die oberste Zeile nicht ausgerichtet sein. Und eigentlich ist es mir egal, dass sie sich so sehr aneinanderreihen, wie ich den Abstand wirklich entfernen möchte.
Bryan Field
0

Meines Wissens ist dies den meisten Widgets eigen, und das Ausmaß der "Auffüllung" ist bei den Telefonherstellern unterschiedlich. Diese Auffüllung ist ein wirklich weißer Raum zwischen dem Bildrand und dem Bild in der 9-Patch-Bilddatei.

Zum Beispiel erhalten Spinner-Widgets auf meinem Droid X mehr Leerraum als Schaltflächen, was es unangenehm macht, wenn Sie einen Spinner inline mit einer Schaltfläche haben, aber auf dem Telefon meiner Frau hat dieselbe Anwendung nicht das gleiche Problem und sieht großartig aus!

Der einzige Vorschlag, den ich hätte, ist, eigene 9 Patch-Dateien zu erstellen und diese in Ihrer Anwendung zu verwenden.

Ahhh die Schmerzen, die Android sind.

Bearbeitet: Polsterung gegen Leerraum klären.

user432209
quelle
0

Dieser Trick hat bei mir funktioniert (für min-sdk> = 18 ).

Ich benutzte android:includeFontPadding="false"und eine negative Marge wie android:layout_marginTop="-11dp"und legte meine TextViewinnen ein FrameLayout( oder eine beliebige Viewgroup ... )

Geben Sie hier die Bildbeschreibung ein

und schließlich Beispielcodes:

<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>
Richi
quelle
1
Dieser Trick funktioniert möglicherweise nicht für verschiedene Schriftarten, Größen oder Layouts.
Adil Soomro
-1

Sieh dir das an:

Richten Sie ImageView horizontal mit EditText aus

Es scheint, dass das Hintergrundbild von EditText einige transparente Pixel enthält, die auch eine Auffüllung hinzufügen.

Eine Lösung besteht darin, den Standardhintergrund von EditText in etwas anderes zu ändern (oder nichts, aber kein Hintergrund für einen EditText ist wahrscheinlich nicht akzeptabel). Das kann gemacht werden, indem das XML-Attribut android: background eingestellt wird.

android:background="@drawable/myEditBackground"
Ixx
quelle
-2

Einfach benutzen

android:padding="0dp"
Juan Bernal
quelle
-5

Verwenden Sie dies in Ihrer ImageView-XML

android: adjustViewBounds = "true"

Anshul Rawat
quelle
Bitte fügen Sie eine Erklärung dazu hinzu
Nico Haase
Ich dachte, das muss verstanden werden. Ich kann nur in XML verwendet werden.
Anshul Rawat