Android: TextView: удаление пробелов и отступов сверху и снизу - PullRequest
168 голосов
/ 22 января 2011

Когда у меня есть TextView с \n в тексте, справа у меня есть два singleLine TextView с, один под другим без промежутков между ними.Я установил следующее для всех трех TextView с.

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

Первая строка слева TextView идеально совпадает с верхней правой TextView.

Вторая строка слева TextView немного выше, чем вторая строка справа внизу TextView.

Кажется, что сверху есть какой-то скрытый отступ.и дно TextView с.Как я могу удалить это?

Ответы [ 17 ]

449 голосов
/ 03 марта 2011
setIncludeFontPadding (boolean includepad)

или XML это будет:

android:includeFontPadding="false"

Установите, включает ли TextView дополнительные верхние и нижние отступы, чтобы освободить место для акцентов, которые идут выше нормального подъема и спуска. По умолчанию установлено значение true.

36 голосов
/ 23 сентября 2011

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

Мое решение?layout_marginBottom="-3dp" на TextView дает вам решение для дна, БАМ!

Хотя, -3dp на layout_marginTop не удается .... тьфу.

29 голосов
/ 19 октября 2016

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

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

Добавление этих двух строк в TextView xml сделает всю работу.
Первый атрибут удаляет отступы, зарезервированные для акцентов, а второй атрибут удаляет интервал, зарезервированный для поддержания надлежащего пространства между двумя строками текста.

Не добавляйте lineSpacingExtra="0dp" в многострочном TextView, так как это может выглядеть неуклюже

9 голосов
/ 22 января 2011

Меня это тоже раздражало, и я нашел ответ, что на самом деле в самом шрифте есть дополнительное пространство, а не TextView. Это довольно раздражает, исходя из фона публикации документов, ограниченного контроля над Android над типографскими элементами. Я бы порекомендовал использовать пользовательский шрифт (например, Bitstream Vera Sans, который лицензирован для распространения), который может не иметь этой проблемы. Я не уверен, что именно так или нет.

4 голосов
/ 03 марта 2017

Я удаляю интервал в моем пользовательском представлении - 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;
    }
}
3 голосов
/ 02 ноября 2017

Так как мое требование переопределить существующий textView, полученный из findViewById(getResources().getIdentifier("xxx", "id", "android"));, поэтому я не могу просто попробовать onDraw() другого ответа.

Но я просто придумываю правильные шаги, чтобы исправить мою проблему,вот окончательный результат от Layout Inspector:

enter image description here

Поскольку я хотел просто удалить верхние пробелы, поэтому мне не нужно выбирать другиешрифт для удаления пробелов.

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

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:

enter image description here

Как видите,курсор внизу имеет дополнительный интервал, но не сверху, поэтому он решил мою проблему.

Второй ключ - , вы не можете просто пропустить любой код , в противном случае он можетне работает.Вот почему вы можете найти, что некоторые люди комментируют, что ответ работает, а некоторые другие комментируют, что он не работает.

Давайте проиллюстрируем, что произойдет, если я удалю один из них.

Без setTypeface(mfont);:

enter image description here

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

enter image description here

Без setIncludeFontPadding(false);:

enter image description here

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

enter image description here

3 голосов
/ 27 января 2016
<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 в true, что сделает базовую линию ImageView нижней.Другие виды могут выравниваться, используя нижнюю часть ImageView, которая сама по себе совпадает с базовой линией TextView.

Это, однако, только фиксирует нижнюю часть отступа, а не верхнюю.

3 голосов
/ 06 марта 2017

Я думаю, что эту проблему можно решить следующим образом:

 <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 выглядит немного выше, чем вторая строка leftText, их базовые линии выровнены.

2 голосов
/ 02 сентября 2018

Простой метод сработал:

setSingleLine();
setIncludeFontPadding(false);

Если это не сработало, попробуйте добавить это выше того кода:

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

Если вам нужна многострочная, возможно, вам понадобитсячтобы точно рассчитать высоту отступа сверху и снизу через временную однострочную TextView (до и после удаления отступа), затем примените результат уменьшения высоты с отрицательным заполнением или некоторый Ghost Layout с переводом Y. Lol

1 голос
/ 04 июня 2019

Если вы используете AppCompatTextView (или начиная с API 27 и далее), вы можете использовать комбинацию этих двух атрибутов, чтобы удалить интервал в первой строке:

XML

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

Kotlin

text.firstBaselineToTopHeight = 0
text.includeFontPadding = false
...