Android: TextView: Usuń odstępy i wypełnienia u góry iu dołu

208

Kiedy mam TextViewz \nw tekście ,, po prawej mam dwie singleLine TextViews, jeden pod drugim bez odstępu pomiędzy nimi. Dla wszystkich trzech ustawiłem następujące TextView.

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

Pierwsza linia lewej TextViewlinii idealnie pokrywa się z prawym górnymTextView .

Druga linia po lewej stronie TextView jest nieco wyższa niż druga linia w prawym dolnym rogu TextView.

Wygląda na to, że na górze i na dole TextViews znajduje się ukryta wyściółka . Jak mogę to usunąć?

Bryan Field
źródło
spróbuj ustawić grawitację tego widoku tekstu na środkowy_werkalny
Dawid Hyży
Cześć, George Bailey, Czy masz rozwiązanie po tak długim czasie? Ten problem też mi się pojawia. Czy możesz podać mi swoje rozwiązanie? dzięki.
mmm2006
1
@ mmm2006, Byłem tak długo, że nie wiem, co skończyłem. Wypróbuj rozwiązania zawarte w odpowiedziach. Jeśli to nie zadziała, zrób nowe pytanie.
Bryan Field,
To mi nie zadziałało
Marty Miller
żadna z poniższych odpowiedzi nie działała dla mnie, możesz pomóc
Richa

Odpowiedzi:

520
setIncludeFontPadding (boolean includepad)

lub w XMLtym byłoby:

android:includeFontPadding="false"

Ustaw, czy ma TextViewzawierać dodatkową górną i dolną wyściółkę, aby zrobić miejsce na akcenty, które przekraczają normalne wejście i zejście. Domyślnie jest to prawda.

użytkownik634545
źródło
3
Ale wydaje się, że zawsze ma 1dpgórne / dolne wypełnienie, czy się mylę? (Używam Developer options -> Show layout bounds)
Autobots
94
includeFontPadding="false"usuwa część przestrzeni, ale nie całość. bardzo dziwny.
theblang
7
Może to być obosieczny miecz. includeFontPaddingdoskonale nadaje się do usuwania wszelkich dodatkowych wypełnień z samej czcionki, ale może powodować problemy w językach, w których wznoszenia i zstępowania są dozwolone. Jeśli to zrobisz, upewnię się, że testujesz języki takie jak hiszpański i tajski, jeśli je wspierasz.
Elliott,
3
Po ustawieniu środowiska uruchomieniowego nie zajmuje górnego wypełnienia, ale dolne wypełnienie nadal tam jest, nawet lewe i prawe wypełnienie? jakieś sugestie?
CoDe
5
To mi nie zadziałało. Nie rozumiem czego mi brakuje. Nadal mam niechciane miejsce na dole mojego TextView
Marty Miller
41

Czuję twój ból. Próbowałem wszystkich odpowiedzi powyżej, w tymsetIncludeFontPadding fałszywe, które nic dla mnie nie zrobiły.

Moje rozwiązanie? layout_marginBottom="-3dp"naTextView dole daje rozwiązanie na dole, BAM!

Chociaż -3dp layout_marginTopnie powiedzie się ... ugh.

Hunterp
źródło
6
Może to doprowadzić do odcięcia dolnej części tekstu
Jason Robinson
2
Naprawdę zły pomysł na użycie ujemnej marży. Lepiej rozważyć niestandardowy widok i narysować tekst dokładnie tak, jak chcesz.
Flynn81
Jeśli taka łatka jest taka, powinieneś również obliczyć stosunek wielkości czcionki.
phnghue
37

Dużo szukałem prawidłowej odpowiedzi, ale nie znalazłem odpowiedzi, która mogłaby dokładnie usunąć wszystkie wypełnienia z TextView, ale w końcu po przejrzeniu oficjalnego dokumentu udało mi się znaleźć tekst dla pojedynczej linii

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

Dodanie tych dwóch linii do TextViewxml wykona pracę.
Pierwszy atrybut usuwa dopełnienie zarezerwowane dla akcentów, a drugi atrybut usuwa odstępy zarezerwowane, aby zachować odpowiednią przestrzeń między dwoma wierszami tekstu.

Pamiętaj, aby nie dodawać lineSpacingExtra="0dp"multilinii TextView, ponieważ może to spowodować, że wygląd będzie niezręczny

Mohammed Atif
źródło
11
dodanie tych dwóch wierszy nie działa dla mnie, a także nie ma zmiany w wypełnieniu
sunil kushwah
@sililkushwah, na pewno zadziała, jeśli robisz to poprawnie. Z przyjemnością pomożemy, jeśli możesz podać więcej szczegółów na temat swojego problemu.
Mohammed Atif
@sililkushwah Prawdopodobnie możesz go wcisnąć na github i udostępnić link
Mohammed Atif
@sililkushwah. Widzę, że używasz czcionki Brandon (czcionka niestandardowa). Czy możesz kiedyś spróbować usunąć fontPathatrybut?
Mohammed Atif
próbowałem tego, ale nie działa, Uwaga: nie chcę żadnego domyślnego wypełnienia w
TextView
14

Jeśli używasz AppCompatTextView(lub API 28odtąd), możesz użyć kombinacji tych 2 atrybutów, aby usunąć odstępy w pierwszym wierszu:

XML

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

Kotlin

text.firstBaselineToTopHeight = 0
text.includeFontPadding = false
Mario Lenci
źródło
11

To mnie również zirytowało, a odpowiedź znalazłem, że w samej czcionce jest więcej miejsca, a nie TextView. Jest to dość irytujące, biorąc pod uwagę tło publikowania dokumentów, ograniczoną kontrolę Androida nad elementami typograficznymi. Polecam użycie niestandardowego kroju pisma (takiego jak Bitstream Vera Sans, który jest licencjonowany do redystrybucji), który może nie mieć tego problemu. Nie jestem jednak pewien, czy tak się dzieje.

Kevin Coppock
źródło
czy masz jakąś darmową czcionkę, aby mnie wskazać? Nie muszę mieć marginesu na wierzchu bez przypisywania ujemnych marginesów! Dziękuję Ci!
sklepienie
11

Możesz spróbować użyć tego atrybutu (ConstraintLayout):layout_constraintBaseline_toBaselineOf

Lubię to:

aplikacja: layout_constraintBaseline_toBaselineOf = "@ + id / textView"

wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

wiatrochron
źródło
10

Usuwam odstępy w moim widoku niestandardowym - NoPaddingTextView.

https://github.com/SenhLinsh/NoPaddingTextView

wprowadź opis zdjęcia tutaj

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
źródło
Czy to pytanie lub odpowiedź?
Tushar
@Tushar To odpowiedź.
Linsh
Dobrze. Czy możesz tutaj dodać wyjaśnienie z kodem.
Tushar
@Tushar Pewnie, ale to trochę więcej.
Linsh
3
Chociaż ten kod może rozwiązać pytanie, w tym wyjaśnienie, w jaki sposób i dlaczego to rozwiązuje problem, naprawdę pomógłby poprawić jakość twojego postu (i uzyskać więcej głosów). Pamiętaj, że odpowiadasz na pytanie czytelników w przyszłości, a nie tylko osoby, która zadaje teraz pytanie! Edytuj swoją odpowiedź, aby dodać wyjaśnienie i podać, jakie ograniczenia i założenia mają zastosowanie.
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>

Dzięki dodatkowemu ImageView możemy ustawić TextView tak, aby był wyrównany do linii bazowej z ImageView i ustawić android:baselineAlignBottom na ImageView wartość true, co spowoduje, że linia podstawowa ImageView będzie na dole. Inne widoki mogą się wyrównywać za pomocą dolnej krawędzi ImageView, która sama jest taka sama jak linia bazowa TextView.

To jednak naprawia tylko dolne wypełnienie, a nie górne.

Viven
źródło
idealne w mojej sytuacji, znacznie lepsze niż usuwanie dopełnienia czcionek. +1
Bawa,
3

Myślę, że ten problem można rozwiązać w następujący sposób:

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

Oto wyniki:

ScreenShot-1

ScreenShot-3

Chociaż linia znaków specjalnych w rightLowerText wygląda nieco wyżej niż druga linia leftText, ich linie bazowe są nadal wyrównane.

Wei Wei
źródło
includeFontPadding = „false” było dokładnie tym, czego potrzebowałem! Dzięki.
hman
3

Ponieważ moim wymaganiem jest zastąpienie istniejącego textView findViewById(getResources().getIdentifier("xxx", "id", "android"));, więc nie mogę po prostu spróbować onDraw()innej odpowiedzi.

Ale po prostu wymyślam właściwe kroki, aby rozwiązać mój problem, oto końcowy wynik Inspektora układu:

wprowadź opis zdjęcia tutaj

Ponieważ chciałem po prostu usunąć górne spacje, więc nie muszę wybierać innej czcionki, aby usunąć dolne spacje.

Oto krytyczny kod, aby to naprawić:

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

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

myTextView.setIncludeFontPadding(false);

Pierwszym kluczem jest ustawienie niestandardowej czcionki „fonts / myCustomFont.otf”, która ma miejsce na dole, ale nie na górze, możesz łatwo to odkryć, otwierając plik otf i klikając dowolną czcionkę w Android Studio:

wprowadź opis zdjęcia tutaj

Jak widać, kursor na dole ma dodatkowe odstępy, ale nie na górze, więc rozwiązało to mój problem.

Drugim kluczem jest to, że nie możesz po prostu pominąć żadnego kodu , w przeciwnym razie może nie działać. To jest powód, dla którego niektórzy ludzie komentują, że odpowiedź działa, a inni komentują, że nie działa.

Zilustrujmy, co się stanie, jeśli usunę jeden z nich.

Bez setTypeface(mfont);:

wprowadź opis zdjęcia tutaj

Bez setPadding(0, 0, 0, 0);:

wprowadź opis zdjęcia tutaj

Bez setIncludeFontPadding(false);:

wprowadź opis zdjęcia tutaj

Bez 3 z nich (tj. Oryginału):

wprowadź opis zdjęcia tutaj

Owoc
źródło
3

Jedyne, co zadziałało, to

android:lineSpacingExtra="-8dp"
Antonis Radz
źródło
3

Zaktualizowany XML

android:fontFamily="monospace"
android:includeFontPadding="false"
SJJ
źródło
Cześć, witamy w Stack Overflow! Odpowiadając na pytanie, powinieneś podać jakieś wyjaśnienie, na przykład co zrobił autor źle i co zrobiłeś, aby to naprawić. Mówię to, ponieważ Twoja odpowiedź została oznaczona jako niskiej jakości i jest obecnie sprawdzana. Możesz edytować swoją odpowiedź, klikając przycisk „Edytuj”.
Federico Grandi
Właściwie zmiana Androida: fontFamily nie jest konieczna, jeśli masz już poprawną czcionkę. Zasadniczo android: includeFontPadding jest jedyną konieczną rzeczą i zostało wspomniane w poprzednich odpowiedziach z tego wątku.
Darek Deoniziak
@DarekDeoniziak Niektóre czcionki mają spacje
SJJ
2

Działa prosta metoda:

setSingleLine();
setIncludeFontPadding(false);

Jeśli to nie zadziałało, spróbuj dodać to powyżej tego kodu:

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

Jeśli potrzebujesz wielu linii, być może będziesz musiał dokładnie obliczyć wysokość dopełniania u góry iu dołu za pomocą temp. Pojedynczej linii TextView (przed i po usunięciu dopełniania), a następnie zastosuj wynik zmniejszenia wysokości z ujemnym dopełnieniem lub układem duchów z tłumaczeniem Y. Lol

phnghue
źródło
0

Możesz spróbować wyrównać dolną część lewego tekstu z dolną częścią drugiego prawego tekstu.

Jems
źródło
Ale wtedy górna linia nie byłaby zgodna. I tak naprawdę nie dbam o to, aby ustawiały się tak bardzo, jak bardzo chciałbym usunąć odstępy.
Bryan Field
0

Według mojej wiedzy jest to nieodłączne dla większości widżetów, a ilość „wypełnienia” różni się w zależności od producenta telefonu. To dopełnienie jest naprawdę białą przestrzenią między ramką obrazu a obrazem w pliku obrazu z 9 poprawkami.

Na przykład na moim Droid X widżety obrotowe mają dodatkową białą przestrzeń niż przyciski, co sprawia, że ​​wygląda to niezręcznie, gdy masz pokrętło w linii z przyciskiem, ale na telefonie mojej żony ta sama aplikacja nie ma tego samego problemu i wygląda świetnie!

Jedyną sugestią, którą chciałbym mieć, jest utworzenie własnych 9 plików łatek i użycie ich w swojej aplikacji.

Ach, bóle, które są na Androida.

Edytowano: Wyjaśnienie dopełnienia vs białe spacje.

użytkownik432209
źródło
0

Ta sztuczka zadziałała dla mnie (dla min-sdk> = 18 ).

Użyłem android:includeFontPadding="false"i ujemny margines jak android:layout_marginTop="-11dp"i umieściłem TextVieww FrameLayout( lub dowolnej grupie ViewGroup ... )

wprowadź opis zdjęcia tutaj

i na koniec przykładowe kody:

<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
źródło
1
Ta sztuczka może nie działać w przypadku różnych czcionek, rozmiarów lub układów.
Adil Soomro,
-1

Zobacz:

Wyrównaj ImageView z EditText w poziomie

Wygląda na to, że obraz tła EditText ma przezroczyste piksele, które również dodają dopełnienie.

Rozwiązaniem jest zmiana domyślnego tła EditText na coś innego (lub nic, ale żadne tło dla EditText jest prawdopodobnie niedopuszczalne). Można to zrobić, ustawiając atrybut android: tło XML.

android:background="@drawable/myEditBackground"
Ixx
źródło
-2

Po prostu użyj

android:padding="0dp"
Juan Bernal
źródło
-5

Użyj tego w swoim ImageView xml

android: adjustViewBounds = "true"

Anshul Rawat
źródło
Dodaj wyjaśnienie na ten temat
Nico Haase,
myślałem, że to trzeba zrozumieć. Mogę być używany tylko w xml.
Anshul Rawat,