Android: TextView: Видаліть відстань і накладки зверху і внизу


208

Якщо у мене є текст TextViewз a \nв тексті ,, праворуч у мене є два singleLine TextViews, один нижче іншого, без проміжків між ними. Я встановив наступне для всіх трьох TextViewс.

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

Перший рядок лівої TextViewлінії ідеально поєднується з правою верхньою TextView.

Другий рядок зліва TextViewтрохи вище другого рядка праворуч внизу TextView.

Здається, вгорі і внизу є якась прихована підкладка TextView. Як я можу це зняти?


спробуйте встановити тяжкість цього текстового перегляду у центрі_вертикалу
Давід Хіджі

Привіт, Джордж Бейлі, чи є у вас рішення через стільки часу? Зараз я теж стикаюся з цією проблемою. Чи можете ви дати мені своє рішення? Дякую.
ммм2006

1
@ mmm2006, Так довго я не знаю, чим я закінчився. Спробуйте рішення у відповідях. Якщо це не спрацює, поставте нове запитання.
Брайан Філд

Це не спрацювало для мене
Марті Міллер

будь-яка з наведених нижче відповідей не працювала для мене, чи можете ви допомогти
Річа

Відповіді:


520
setIncludeFontPadding (boolean includepad)

або в XMLцьому буде:

android:includeFontPadding="false"

Встановіть, чи TextViewвключає додаткові накладки на верхній і нижній частині, щоб звільнити місця для акцентів, які виходять за рамки звичайного підйому та спуску. За замовчуванням вірно.


3
Але, здається, завжди є 1dpверхній / нижній прокладки, я помиляюся? (Я використовую Developer options -> Show layout bounds)
Autobots

94
includeFontPadding="false"видаляє частину місця, але не все це. дуже дивно.
theblang

7
Це може бути меч з двома кінцями. includeFontPaddingвідмінно підходить для видалення будь-яких додаткових накладок із самого шрифту, але це може спричинити проблеми на мовах, у яких є висхідні та спадні. Я би переконався, що якщо ви це зробите, ви перевірите такі мови, як іспанська та тайська, якщо ви їх підтримуєте.
Елліотт

3
Після встановлення часу виконання не буде взято верхню підкладку, а нижню прокладку все ще є, навіть ліву та праву накладки також? будь-яка пропозиція?
CoDe

5
Це не спрацювало для мене. Я не розумію, чого мені не вистачає. У мене все ще є небажаний простір у нижній частині мого TextView
Марті Міллер

41

Я відчуваю твій біль. Я випробував кожну відповідь вище, включаючи setIncludeFontPaddingпомилкову, яка нічого не зробила для мене.

Моє рішення? layout_marginBottom="-3dp"з TextViewподарунками дає вам рішення на дно, БАМ!

Хоча, -3dp на провал layout_marginTop.... тьфу.


6
Це може призвести до того, що внизу текст може бути відрізаний
Джейсон Робінсон

2
Дійсно погана ідея використання негативної маржі. Краще розглянути спеціальний перегляд і намалювати текст саме так, як вам потрібно.
Flynn81

Якщо виправлення подібним чином, вам слід також розрахувати співвідношення розміру шрифту.
phnghue

37

Я багато шукав належної відповіді, але не там, де я міг би знайти відповідь, який би міг точно видалити всі підкладки з TextView , але, нарешті, після проходження офіційного документа отримав розмову для текстових текстових рядків

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

Додавання цих двох рядків до TextViewxml зробить роботу.
Перший атрибут видаляє прокладку, зарезервовану для наголосів, а другий атрибут видаляє інтервал, зарезервований для збереження належного простору між двома рядками тексту.

Переконайтеся, що не додавати lineSpacingExtra="0dp"багаторядковий TextView, оскільки це може зробити вигляд незграбним


11
додавання цих двох рядків не працює для мене, а також немає змін в набиванні
sunil kushwah

@sunilkushwah, це обов'язково спрацює, якщо ви робите це правильно. Будемо раді допомогти, якщо ви зможете надати більш детальну інформацію про свою проблему.
Мухаммед Атіф

@sunilkushwah Ви, ймовірно, можете натиснути на github та поділитися посиланням
Mohammed Atif

@sunilkushwah Я бачу, що ви використовуєте шрифт Brandon (спеціальний шрифт). Ви можете один раз спробувати видалити fontPathатрибут?
Мухаммед Атіф

Я спробував це, але це не працює, Примітка: я не хочу будь-якої прокладки за замовчуванням у TextView
sunil kushwah

14

Якщо ви користуєтесь AppCompatTextView(або API 28далі), ви можете використовувати комбінацію цих двох атрибутів, щоб видалити пробіл у першому рядку:

XML

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

Котлін

text.firstBaselineToTopHeight = 0
text.includeFontPadding = false

11

Це мене також дратувало, і я знайшов відповідь, що насправді в самому шрифті є додатковий простір, а не TextView. Це дуже дратує, оскільки ви бачите обмежений обсяг контролю над типографічними елементами Android, який має Android. Я рекомендую використовувати спеціальний шрифт (наприклад, Bitstream Vera Sans, який має ліцензію на перерозподіл), який може не мати цієї проблеми. Я конкретно не впевнений, чи це робить, чи ні.


у вас є якийсь безкоштовний шрифт, щоб вказати на мене? У мене не повинно бути маржі на вершині, не призначаючи негативну маржу! Дякую!
склепіння

11

Ви можете спробувати використовувати цей атрибут (ConstraintLayout):layout_constraintBaseline_toBaselineOf

Подобається це:

додаток: layout_constraintBaseline_toBaselineOf = "@ + id / textView"

введіть тут опис зображення

введіть тут опис зображення


10

Я видаляю інтервал у моєму власному представленні - NoPaddingTextView.

https://github.com/SenhLinsh/NoPaddingTextView

введіть тут опис зображення

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

Це питання чи відповідь?
Тушар

@Tushar Це відповідь.
Лінш

Гаразд. Чи можете ви додати тут пояснення з кодом.
Тушар

@Tushar Звичайно, але це трохи більше.
Лінш

3
Хоча цей код може вирішити питання, включаючи пояснення, як і чому це вирішує проблему, справді допоможе покращити якість вашої публікації (та отримати голоси). Пам’ятайте, що ви відповідаєте на запитання читачів у майбутньому, а не лише про людину, яка зараз запитує! Будь ласка, відредагуйте свою відповідь, щоб додати пояснення та вказати, які обмеження та припущення застосовуються.
Макіен

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>

За допомогою додаткового ImageView ми можемо встановити TextView для базової лінії, вирівняної з ImageView, і встановити android:baselineAlignBottomна ImageView справжню, що зробить базову лінію ImageView внизу. Інші представлення даних можуть вирівняти себе, використовуючи нижню частину ImageView, яка сама є такою ж, як і базову лінію TextView.

Однак це фіксує лише нижню частину прокладки, а не верхню частину.


ідеально підходить для моєї ситуації, набагато краще, ніж видаляти прокладки шрифтів. +1
Бава

3

Я думаю, що цю проблему можна вирішити таким чином:

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

Це результати:

ScreenShot-1

ScreenShot-3

Хоча рядок спеціальних символів у rightLowerText виглядає трохи вище, ніж другий рядок зліваText, їхні базові лінії викладені врівень.


includeFontPadding = "false" було саме те, що мені потрібно! Дякую.
hman

3

Оскільки моя вимога переосмислює наявний textView findViewById(getResources().getIdentifier("xxx", "id", "android"));, то я не можу просто спробувати onDraw()іншу відповідь.

Але я просто з'ясував правильні кроки, щоб вирішити свою проблему, ось кінцевий результат від інспектора макета:

введіть тут опис зображення

Оскільки те, що я хотів, - це просто видалити верхні пробіли, тому мені не потрібно вибирати інший шрифт, щоб видалити пробіли внизу.

Ось критичний код для його виправлення:

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

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

myTextView.setIncludeFontPadding(false);

Першим ключем є встановлений спеціальний шрифт "fonts / myCustomFont.otf", який має простір внизу, але не вгорі, ви можете легко зрозуміти це, відкривши файл otf і натисніть будь-який шрифт в android Studio:

введіть тут опис зображення

Як бачите, курсор знизу має додатковий інтервал, але не вгорі, тому він вирішив мою проблему.

Другий ключ - ви не можете просто пропустити будь-який код , інакше він може не працювати. Ось чому ви можете виявити, що деякі люди коментують, що відповідь працює, а інші люди коментують, що вона не працює.

Давайте проілюструємо, що буде, якщо я видалю одну з них.

Без setTypeface(mfont);:

введіть тут опис зображення

Без setPadding(0, 0, 0, 0);:

введіть тут опис зображення

Без setIncludeFontPadding(false);:

введіть тут опис зображення

Без 3 з них (тобто оригінал):

введіть тут опис зображення



3

Оновлений XML

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

Привіт, Ласкаво просимо до Stack Overflow! Коли ви відповідаєте на запитання, вам слід включити якесь пояснення, наприклад, що автор зробив неправильно і що ви зробили, щоб виправити це. Я кажу вам про це, тому що ваша відповідь позначена як неякісна і зараз її переглядають. Ви можете змінити свою відповідь, натиснувши кнопку "Редагувати".
Федеріко Гранді

Фактично змінюється Android: fontFamily не потрібен, якщо у вас вже є правильний шрифт. В основному андроїд: includeFontPadding - єдине, що потрібно, і це було зазначено в попередніх відповідях з теми.
Дарек Деонізяк

@DarekDeoniziak У деяких шрифтах є пробіли
SJJ

2

Простий метод працював:

setSingleLine();
setIncludeFontPadding(false);

Якщо це не спрацювало, спробуйте додати це вище цього коду:

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

Якщо вам потрібна багаторядкова лінія, можливо, вам потрібно буде точно обчислити висоту оббивки зверху і знизу за допомогою одного рядка temp TextView (до та після видалення прокладки), а потім застосувати результат зменшення висоти за допомогою негативного прокладки або деякого макета Ghost з перекладом Y. Лол


0

Ви можете спробувати вирівняти нижню частину подання лівого тексту з нижньою частиною 2-го правого тексту.


Але тоді верхня лінія не вирівнювалася б. І насправді я не переймаюся тим, як вони шикуються настільки, наскільки я хотів би прибрати пробіли.
Брайан Філд

0

Наскільки мені відомо, це властиво більшості віджетів, і кількість «прокладки» відрізняється у виробників телефонів. Ця підкладка - це дійсно пробіл між рамкою зображення та зображенням у файлі зображень 9 патчів.

Наприклад, на моєму Droid X віджети спінеру отримують додаткове пробіл, ніж кнопки, тому це виглядає незручно, коли у вас є спінер, вбудований кнопкою, але на телефоні моєї дружини це ж додаток не має такої ж проблеми і виглядає чудово!

Єдина пропозиція, яку я мав би, - це створити власні 9 патч-файлів та використовувати їх у своїй програмі.

Ахх, болі Android.

Відредаговано: Уточнення прокладки та пробілу.


0

Цей трюк спрацював для мене (для min-sdk> = 18 ).

Я використав android:includeFontPadding="false"і негативний запас, як android:layout_marginTop="-11dp"і вставте TextViewвсередину FrameLayout( або будь-яку ViewGroup ... )

введіть тут опис зображення

і, нарешті, вибіркові коди:

<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
Цей трюк може не працювати для різних шрифтів, розмірів або макетів.
Аділ Соомро

-1

Дивіться це:

Вирівняйте ImageView за допомогою EditText горизонтально

Здається, що фонове зображення EditText має кілька прозорих пікселів, які також додають набивання.

Рішення полягає в тому, щоб змінити фон за замовчуванням EditText на щось інше (або нічого, але жоден фон для EditText, ймовірно, не прийнятний). Для цього можна встановити атрибут android: background XML.

android:background="@drawable/myEditBackground"


-5

Використовуйте це у вашому ImageView xml

android: prilagodViewBounds = "вірно"


Будь ласка, додайте пояснення з цього приводу
Ніко Хааз

Я думав, це треба розуміти. Я можу використовуватись лише в xml.
Аншул Рават
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.