Android:TextView:删除顶部和底部的间距和填充


206

当我在文本中TextView带有a \n时,在右侧,我有两个singleLine TextViews,一个在另一个下面,两个之间没有空格。我为所有三个设置了以下内容TextView

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

左边的第一行TextView与右边的右对齐TextView

左边TextView的第二行比右边底部的第二行高一点TextView

似乎在TextViews 的顶部和底部有某种隐藏的填充。我该如何删除?


尝试将此文本视图的重力设置为center_vertical
DawidHyży13年

嗨,乔治·贝利(George Bailey),经过这么长时间,您有解决方案吗?我现在也遇到这个问题。能给我您的解决方案吗?谢谢。
mmm2006年

1
@ mmm2006,已经很久了,我不知道自己最终在做什么。尝试答案中的解决方案。如果那不起作用,请提出一个新问题。
布赖恩·菲尔德

这对我不起作用
Marty Miller

以下任何答案对我都没有帮助,您能帮忙吗
Richa

Answers:


520
setIncludeFontPadding (boolean includepad)

XML这将是:

android:includeFontPadding="false"

设置是否TextView包括额外的顶部和底部填充,以便为超出正常上升和下降高度的重音腾出空间。默认值为true。


3
但似乎总是有1dp顶部/底部填充,我错了吗?(我使用Developer options -> Show layout bounds
Autobots 2014年

94
includeFontPadding="false"确实删除了一些空间,但不是全部。很奇怪。
theblang 2014年

7
这可以是一把双刃剑。includeFontPadding非常适合从字体本身中删除任何其他填充,但是它可能导致具有升序和降序的语言出现问题。如果您这样做,我会确保您可以测试西班牙语和泰语等语言(如果支持)。
Elliott 2015年

3
设置运行时后,它是否不使用顶部填充,而仍然使用底部填充,甚至还包括左侧和右侧填充?有什么建议吗?
CoDe 2015年

5
这对我不起作用。我不明白我在想什么。我仍然有我的TextView底部多余的空格
马蒂·米勒

41

我感到你很痛苦。我已经尝试了以上所有答案,包括setIncludeFontPaddingto否,这对我没有任何帮助。

我的解决方案? layout_marginBottom="-3dp"TextView为您提供了底部,BAM的解决方案!

虽然,-3dp on layout_marginTop失败....呃。


6
这可能导致文本的底部可能被截断
Jason Robinson

2
使用负边距确实是个坏主意。最好考虑使用自定义视图并根据需要精确绘制文本。
Flynn81 '16

如果是这样的补丁,您也应该计算字体大小的比率。
phnghue

37

我在适当的答案中进行了大量搜索,但找不到可以从中完全删除所有填充的答案TextView,但是经过官方文档后,终于找到了解决单行文本的方法

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

将这两行添加到TextViewxml中即可完成工作。
第一个属性删除保留用于重音符号的填充,第二个属性删除保留以保持两行文本之间适当间距的间距。

确保不要添加lineSpacingExtra="0dp"多行TextView,因为它可能会使外观笨拙


11
添加这两行对我
不起作用

@sunilkushwah,如果操作正确,它肯定会起作用。如果您可以提供有关问题的更多详细信息,将非常乐意为您提供帮助。
Mohammed Atif

@sunilkushwah您可能可以在github上推送它并共享链接
Mohammed Atif

@sunilkushwah,我看到您使用的是Brandon字体(自定义字体)。您可以一次尝试删除fontPath属性吗?
Mohammed Atif

我尝试了此操作,但不起作用,请注意:我不需要TextView中的任何默认填充
sunil kushwah

13

如果使用AppCompatTextView(或从API 28向前),则可以使用这两个属性的组合来删除第一行的间距:

XML格式

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

科特林

text.firstBaselineToTopHeight = 0
text.includeFontPadding = false

11

这也让我很烦,我发现的答案是字体本身实际上有额外的空间,而不是TextView。由于文档发布的背景,Android对印刷元素的控制有限,这非常令人恼火。我建议使用可能没有此问题的自定义字体(例如,Bitstream Vera Sans,已获得许可进行重新分发)。我不确定具体是否可以。


你有一些免费的字体可以指向我吗?我需要不分配负边距就没有边距!谢谢!
金库

11

您可以尝试使用此属性(ConstraintLayout):layout_constraintBaseline_toBaselineOf

像这样:

app: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这是一个答案。
林什

好。您能在这里用代码添加一些解释吗?
Tushar

@Tushar当然,还有更多。
林什

3
尽管这段代码可以解决问题,但包括如何解决以及如何解决该问题的说明,确实可以帮助提高帖子的质量(并提高投票率)。请记住,您将来会为读者回答问题,而不仅仅是现在问的人!请编辑您的答案以添加说明,并指出适用的限制和假设。
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>

通过额外的ImageView,我们可以将TextView设置为与ImageView基线对齐,并设置 android:baselineAlignBottom上的为true,这将使ImageView的基线为底端。其他视图可以使用本身与TextView基线相同的ImageView底部对齐。

但是,这仅固定填充物底部而不固定顶部。


最适合我的情况,比删除字体填充更好。+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

屏幕截图3

尽管rightLowerText中的特殊字符行看起来比leftText的第二行高一点,但它们的基线仍然对齐。


includeFontPadding =“ false”正是我所需要的!谢谢。
hman

3

由于我的要求是覆盖现有的textView from findViewById(getResources().getIdentifier("xxx", "id", "android"));,因此我不能简单地尝试onDraw()其他答案。

但是我只是想出解决问题的正确方法,这是Layout Inspector的最终结果:

在此处输入图片说明

因为我想要的只是删除顶部空格,所以我不必选择其他字体来删除底部空格。

这是修复它的关键代码:

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个(即原始版本):

在此处输入图片说明



2

工作简单的方法:

setSingleLine();
setIncludeFontPadding(false);

如果不起作用,请尝试在该代码上方添加以下代码:

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

如果您需要多行,也许您需要通过临时单行TextView(在删除填充之前和之后)精确计算填充顶部和底部的高度,然后使用负填充或使用平移Y的某些Ghost布局应用降低高度的结果。大声笑


1

更新的XML

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

嗨,欢迎来到Stack Overflow!当您回答问题时,您应该提供某种解释,例如作者做错了什么以及您为解决该问题所做的工作。我之所以这样告诉您,是因为您的答案被标记为低质量,目前正在接受审核。您可以通过单击“编辑”按钮来编辑答案。
Federico Grandi

如果您已经拥有正确的字体,则实际上不需要更改android:fontFamily。基本上,只有android:includeFontPadding是必需的,并且在前面的线程答复中已经提到了它。
Darek Deoniziak

@DarekDeoniziak有些字体带有空格
SJJ

0

您可能想要尝试将左文本视图的底部与右二文本视图的底部对齐。


但随后,第一行将无法排队。实际上,我并不关心它们排列得像我真正想要删除的间距那样大。
布莱恩·菲尔德

0

据我所知,这是大多数小部件固有的,并且“填充”的数量在手机制造商之间有所不同。此填充实际上是图像边框和9个补丁图像文件中的图像之间的空白。

例如,在我的Droid X上,微调器小部件获得的空间比按钮多,这使您在将微调器与按钮内联时显得尴尬,但在我妻子的手机上,相同的应用程序没有相同的问题,看起来很棒!

我唯一的建议是创建自己的9个补丁文件,并在您的应用程序中使用它们。

啊,这就是Android的烦恼。

编辑:澄清填充与空白。


0

这个技巧对我有用(对于min-sdk> = 18)。

我曾经android:includeFontPadding="false"和一个负利润率android:layout_marginTop="-11dp",把我TextViewFrameLayout或任何的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
此技巧可能不适用于不同的字体,大小或布局。
Adil Soomro

-1

看到这个:

将ImageView与EditText水平对齐

似乎EditText的背景图像具有一些透明像素,这些像素也增加了填充。

一种解决方案是将EditText的默认背景更改为其他内容(或什么都不做,但是EditText的背景可能不可接受)。可以通过设置android:background XML属性来实现。

android:background="@drawable/myEditBackground"


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.