ChatGPT解决这个技术问题 Extra ChatGPT

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

当我在文本中有一个 TextView 和一个 \n 时,在右边我有两个 singleLine TextView,一个在另一个下方,中间没有空格。我为所有三个 TextView 设置了以下内容。

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

左侧 TextView 的第一行与右上角 TextView 完美对齐。

左侧 TextView 的第二行略高于右下 TextView 的第二行。

TextView 的顶部和底部似乎有某种隐藏的填充。我怎样才能删除它?

尝试将此文本视图的重力设置为 center_vertical
嗨,George Bailey,这么长时间后你有解决方案吗?我现在也遇到这个问题。你能给我你的解决方案吗?谢谢。
@ mmm2006,这么久了,我不知道我最终做了什么。尝试答案中的解决方案。如果这不起作用,请提出一个新问题。
这对我不起作用
以下任何答案都不适合我,你能帮忙吗

U
User1
setIncludeFontPadding (boolean includepad)

或在 XML 中,这将是:

android:includeFontPadding="false"

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


但它似乎总是有一个 1dp 顶部/底部填充,我错了吗?(我使用 Developer options -> Show layout bounds
includeFontPadding="false" 确实删除了一些空间,但不是全部。很奇怪。
这可能是一把双刃剑。 includeFontPadding 非常适合从字体本身移除任何额外的填充,但它可能会导致具有升序和降序的语言出现问题。我会确保如果你这样做,你会测试西班牙语和泰语等语言,如果你支持的话。
设置运行时后,它没有采用顶部填充,但底部填充仍然存在,甚至左右填充也是如此?有什么建议吗?
这对我不起作用。我不明白我错过了什么。我的 TextView 底部仍然有不需要的空间
M
Mohammed Atif

我搜索了很多正确的答案,但没有找到可以完全删除 TextView 中所有填充的答案,但最终在通过 official doc 后,我找到了 单行文本强>

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

将这两行添加到 TextView xml 即可。
第一个属性删除为重音保留的填充,第二个属性删除为保持两行文本之间的适当间距而保留的间距。

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


添加这两行对我不起作用,填充也没有变化
@sunilkushwah,如果你做得好,它肯定会起作用。如果您能提供有关您的问题的更多详细信息,我们将很乐意提供帮助。
@sunilkushwah 你可以把它推到 github 上并分享链接
@sunilkushwah 我看到您正在使用 Brandon 字体(自定义字体)。您可以通过删除 fontPath 属性尝试一次吗?
我试过了,但它不起作用,注意:我不想在 TextView 中使用任何默认填充
P
Praful Bhatnagar

我感觉到你的痛苦。我已经尝试了上面的每个答案,包括将 setIncludeFontPadding 设置为 false,这对我没有任何帮助。

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

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


这可能导致文本的底部可能被截断
使用负边距真的很糟糕。最好考虑自定义视图并完全按照您的需要绘制文本。
如果是这样的补丁,你也应该计算字体大小的比例。
S
Suraj Rao

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

像这样:

应用程序:layout_constraintBaseline_toBaselineOf="@+id/textView"

https://i.stack.imgur.com/eFh72.png

https://i.stack.imgur.com/y8SGG.png


肿瘤坏死因子。这也帮助我解决了另一个问题,即有一个包含多尺寸文本的文本视图。使用此解决方案,我可以使用具有不同文本大小的多个文本视图,并且在基线约束的帮助下,我可以像它的一个文本视图一样显示它们。
A
Ali

更新的 XML

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

您好,欢迎来到 Stack Overflow!当你回答一个问题时,你应该包括某种解释,比如作者做错了什么以及你做了什么来解决它。我告诉你这个是因为你的答案被标记为低质量,目前正在审查中。您可以通过点击“编辑”按钮来edit您的答案。
如果您已经拥有正确的字体,则实际上不需要更改 android:fontFamily。基本上 android:includeFontPadding 是唯一必要的,它已在线程的先前答案中提到。
@DarekDeoniziak 有些字体有空格
T
Tim

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

XML

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

科特林

text.firstBaselineToTopHeight = 0
text.includeFontPadding = false

一样,不工作。顶部还有额外的填充
S
Sahil Bansal

添加 android:includeFontPadding="false" 看看是否有帮助。并使文本视图大小与文本大小相同,而不是“包装内容”。它肯定会工作。


K
Kevin Coppock

这也让我很恼火,我发现的答案是字体本身实际上有额外的空间,而不是 TextView。这是相当恼人的,来自文档发布背景,您对 Android 对排版元素的控制量有限。我建议使用可能没有此问题的自定义字体(例如 Bitstream Vera Sans,它已获得再分发许可)。不过,我不确定它是否确实如此。


你有一些免费的字体可以指点我吗?如果不分配负边距,我需要在顶部没有边距!谢谢!
L
Linsh

我删除了自定义视图中的间距——NoPaddingTextView。

https://github.com/SenhLinsh/NoPaddingTextView

https://i.stack.imgur.com/SWEedl.png

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 这是一个答案。
虽然此代码可能会解决问题,但including an explanation如何以及为什么解决问题将真正有助于提高您的帖子质量(并获得投票)。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人!请编辑您的答案以添加解释,并说明适用的限制和假设。
TextView 子类化,尤其是覆盖 onDraw 在我看来是一个非常糟糕的主意。这样一来,您将失去 Google 所做或将在未来版本中所做的所有花哨装饰(当然也没有 AppCompat 的功能),并且您无法匹配此控件的 OEM 特定样式设备,如果有的话。
它可能有效,但在每个度量事件上创建新的 TextView 内存效率不高。 Android Lint 不鼓励在 draw()、onDraw() 或任何与布局相关的方法中创建新对象,并且在布局期间可以调用未知时间。
林果皞

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

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

https://i.stack.imgur.com/FnA7o.png

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

这是修复它的关键代码:

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 中的任何字体轻松找出这一点:

https://i.stack.imgur.com/xRobI.png

如您所见,底部的光标有额外的间距,但顶部没有,所以它解决了我的问题。

第二个关键是你不能简单地跳过任何代码,否则它可能不起作用。这就是为什么您会发现有些人评论说答案有效,而其他人评论说答案无效。

让我们说明如果我删除其中一个会发生什么。

没有 setTypeface(mfont);

https://i.stack.imgur.com/KbkzK.png

没有 setPadding(0, 0, 0, 0);

https://i.stack.imgur.com/yydTK.png

没有 setIncludeFontPadding(false);

https://i.stack.imgur.com/JOQnQ.png

没有其中的 3 个(即原件):

https://i.stack.imgur.com/ELEwZ.png


V
Viven
<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 的基线对齐,并将 ImageView 上的 android:baselineAlignBottom 设置为 true,这将使 ImageView 的基线位于底部。其他视图可以使用 ImageView 的底部对齐自身,该底部本身与 TextView 的基线相同。

然而,这只修复了填充底部而不是顶部。


非常适合我的情况,比删除字体填充要好得多。 +1
W
Wei Wei

我认为这个问题可以这样解决:

 <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 的第二行高一点,但它们的基线仍然对齐。


includeFontPadding="false" 正是我需要的!谢谢。
p
phnghue

简单的方法有效:

setSingleLine();
setIncludeFontPadding(false);

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

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

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


A
Antonis Radz

唯一有效的是

android:lineSpacingExtra="-8dp"

J
Jems

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


但那时顶线不会排队。实际上,我并不关心它们排成一行,因为我真的很想删除间距。
u
user432209

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

例如,在我的 Droid X 上,微调器小部件比按钮获得更多的空白,这使得当你有一个与按钮内联的微调器时看起来很尴尬,但在我妻子的手机上,相同的应用程序没有同样的问题,而且看起来很棒!

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

啊,Android的痛苦。

编辑:澄清填充与空白。


u
ultra.deep

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

我使用了 android:includeFontPadding="false"负边距,例如 android:layout_marginTop="-11dp",并将我的 TextView 放入 FrameLayout或任何 ViewGroup...

https://i.stack.imgur.com/K1Kn8.png

最后是示例代码:

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

这个技巧可能不适用于不同的字体、大小或布局。
J
Jack

使用约束布局作为你的根视图,然后添加一个指南助手。

例子:

<TextView
 android:id="@+id/textView1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" 
 app:layout_constraintTop_toTopOf="parent" 
 app:layout_constraintStart_toStartOf="parent" />

<TextView
 android:id="@+id/textView2"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" 
 app:layout_constraintStart_toStartOf="parent"
 app:layout_constraintTop_toBottomOf="@+id/guideline" />

<androidx.constraintlayout.widget.Guideline
 android:id="@+id/guideline"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:orientation="horizontal"
 app:layout_constraintGuide_begin="20dp" />

属性 layout_constraintGuide_begin 值只是示例,它取决于您的需要。


J
Jeffrey Blattman

您可以使用此处列出的一些技巧(负边距、字体填充等)部分解决此问题,但您无法绕过字体本身的大小 [1]。字体的每个“单元格”的固定高度必须足够大,以容纳所有语言中最高的字符。

如果您使用其他答案中列出的技巧,则可以剪裁字体。

解决方案是向您的设计师解释这是字体的打包方式,并让他们在设计中考虑到这一点。当它被翻译成其他语言时,现在不要把事情搞砸,以便在路上提交错误。

[1] 我想人们可以用压缩的上升和下降来打包自己的字体。


P
Prashant Rawat

这对我有用:

android:minHeight="0dp"

这没有提供问题的答案。一旦你有足够的reputation,你就可以comment on any post;相反,provide answers that don't require clarification from the asker。 - From Review
C
Community

看到这个:

Align ImageView with EditText horizontally

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

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

android:background="@drawable/myEditBackground"

A
Anshul Rawat

在您的 ImageView xml 中使用它

机器人:adjustViewBounds =“真”


请对此添加一些解释
我认为这必须被理解。我只能在 xml 中使用。