Android TextView 去除顶部和底部空间的方法

发布于 2024-11-18 19:30:01 字数 392 浏览 6 评论 0原文

当我将以下 XML 包含到 layout 文件中时,我可以看到下图。如果您看到它,您可能会意识到 TextView 有顶部和底部空间。

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="E1"
android:background="#ff00ff00"/>

在此处输入图像描述

我希望删除空格。如何去除它?它叫什么? 如果有人有线索..请告诉我。提前致谢。

When I include the below XML to layout file, I can see the below image. If you see it, you could realize that the TextView has top and bottom space.

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="E1"
android:background="#ff00ff00"/>

enter image description here

I wish to remove the space. How to remove it? What is it called?
If anyone has clue.. please let me know. Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

叫嚣ゝ 2024-11-25 19:30:01

尝试 android:includeFontPadding="false" 看看是否有帮助。根据我的经验,这会有所帮助,但无法将 TextView 尺寸减小到精确的像素完美文本大小。

唯一的替代方案(可能会也可能不会给出更好的结果)是稍微作弊并硬连线尺寸以匹配文本大小,例如 "24sp" 而不是 "wrap_content"< /code> 为高度。

Try android:includeFontPadding="false" to see if it helps. In my experience that will help a little bit, but there's no way of reducing the TextView dimensions to the exact pixel-perfect text size.

The only alternative, which may or may not give better results, is to cheat a bit and hard-wire the dimensions to match the text size, e.g. "24sp" instead of "wrap_content" for the height.

芯好空 2024-11-25 19:30:01

我也有同样的问题。属性 android:includeFontPadding="false" 对我不起作用。我用这种方式解决了这个问题:

public class TextViewWithoutPaddings extends TextView {

    private final Paint mPaint = new Paint();

    private final Rect mBounds = new Rect();

    public TextViewWithoutPaddings(Context context) {
        super(context);
    }

    public TextViewWithoutPaddings(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TextViewWithoutPaddings(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        final String text = calculateTextParams();

        final int left = mBounds.left;
        final int bottom = mBounds.bottom;
        mBounds.offset(-mBounds.left, -mBounds.top);
        mPaint.setAntiAlias(true);
        mPaint.setColor(getCurrentTextColor());
        canvas.drawText(text, -left, mBounds.bottom - bottom, mPaint);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        calculateTextParams();
        setMeasuredDimension(mBounds.width() + 1, -mBounds.top + 1);
    }

    private String calculateTextParams() {
        final String text = getText().toString();
        final int textLength = text.length();
        mPaint.setTextSize(getTextSize());
        mPaint.getTextBounds(text, 0, textLength, mBounds);
        if (textLength == 0) {
            mBounds.right = mBounds.left;
        }
        return text;
    }
}

I had the same problem. Attribute android:includeFontPadding="false" does not work for me. I've solved this problem in this way:

public class TextViewWithoutPaddings extends TextView {

    private final Paint mPaint = new Paint();

    private final Rect mBounds = new Rect();

    public TextViewWithoutPaddings(Context context) {
        super(context);
    }

    public TextViewWithoutPaddings(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TextViewWithoutPaddings(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        final String text = calculateTextParams();

        final int left = mBounds.left;
        final int bottom = mBounds.bottom;
        mBounds.offset(-mBounds.left, -mBounds.top);
        mPaint.setAntiAlias(true);
        mPaint.setColor(getCurrentTextColor());
        canvas.drawText(text, -left, mBounds.bottom - bottom, mPaint);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        calculateTextParams();
        setMeasuredDimension(mBounds.width() + 1, -mBounds.top + 1);
    }

    private String calculateTextParams() {
        final String text = getText().toString();
        final int textLength = text.length();
        mPaint.setTextSize(getTextSize());
        mPaint.getTextBounds(text, 0, textLength, mBounds);
        if (textLength == 0) {
            mBounds.right = mBounds.left;
        }
        return text;
    }
}
毁梦 2024-11-25 19:30:01

android:includeFontPadding="false" 非常好,但它没有准确地得到它。有时您需要边界线的准确性,因此您可以通过应用负边距来自行计算:

尝试将底部和顶部边距设置为负值。

像这样:

android:layout_marginTop="-5dp"
android:layout_marginBottom="-5dp"

相应地调整值。

android:includeFontPadding="false" is pretty good but it does not get it precisely. sometimes you want border line accuracy so you can figure it out yourself by applying negative margins:

try setting your bottom and top margins to a negative value.

something like this:

android:layout_marginTop="-5dp"
android:layout_marginBottom="-5dp"

adjust the values accordingly.

小兔几 2024-11-25 19:30:01

这是拯救我们的代码。它是使用 maksimko 中的单声道 C# 代码进行改编的:

public class TopAlignedTextView extends TextView {

    public TopAlignedTextView(Context context) {
        super(context);
    }

    /*This is where the magic happens*/
    @Override
    protected void onDraw(Canvas canvas){

        float offset = getTextSize() - getLineHeight();
        canvas.translate(0, offset);
        super.onDraw(canvas);
    }
}

仍然需要使用 textView.setIncludeFontPadding(false ) 因为我们将 TextViews 与不同的字体大小对齐。

This is the code that saved our day. It was adapted using mono C# code from maksimko:

public class TopAlignedTextView extends TextView {

    public TopAlignedTextView(Context context) {
        super(context);
    }

    /*This is where the magic happens*/
    @Override
    protected void onDraw(Canvas canvas){

        float offset = getTextSize() - getLineHeight();
        canvas.translate(0, offset);
        super.onDraw(canvas);
    }
}

Still had to play around with textView.setIncludeFontPadding(false) because we were aligning TextViews with different font sizes.

一桥轻雨一伞开 2024-11-25 19:30:01

我遇到了同样的问题。
这是一个很好的答案:如何对齐文本到 TextView 的顶部?

但是代码还没有完成,并且不支持所有字体大小。将行更改

int additionalPadding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, getContext().getResources().getDisplayMetrics());

int additionalPadding = getTextSize() - getLineHeight();

完整的 C# 代码(单声道)删除顶部偏移量:

public class TextControl : TextView {
    public TextControl (Context context) : base (context)
    {
        SetIncludeFontPadding (false);
        Gravity = GravityFlags.Top;
    }

    protected override void OnDraw (Android.Graphics.Canvas canvas)
    {
        if (base.Layout == null)
            return;

        Paint.Color = new Android.Graphics.Color (CurrentTextColor);
        Paint.DrawableState = GetDrawableState ();

        canvas.Save ();

        var offset = TextSize - LineHeight;
        canvas.Translate (0, offset);

        base.Layout.Draw (canvas);

        canvas.Restore ();
    }
}

I faced the same problem.
Here's a good answer: How to align the text to top of TextView?

But code is little unfinished and don't support all font sizes. Change the line

int additionalPadding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, getContext().getResources().getDisplayMetrics());

to

int additionalPadding = getTextSize() - getLineHeight();

Complete C# code (mono) removes top offset:

public class TextControl : TextView {
    public TextControl (Context context) : base (context)
    {
        SetIncludeFontPadding (false);
        Gravity = GravityFlags.Top;
    }

    protected override void OnDraw (Android.Graphics.Canvas canvas)
    {
        if (base.Layout == null)
            return;

        Paint.Color = new Android.Graphics.Color (CurrentTextColor);
        Paint.DrawableState = GetDrawableState ();

        canvas.Save ();

        var offset = TextSize - LineHeight;
        canvas.Translate (0, offset);

        base.Layout.Draw (canvas);

        canvas.Restore ();
    }
}
你又不是我 2024-11-25 19:30:01

只是想添加到 DynamicMind的回答,您看到 TextView 周围有间距的原因是9 块背景中的填充默认使用。

9 补丁技术允许您指定一个内容区域,这实际上是填充。除非您明确设置视图的填充,否则将使用该填充。例如,当您以编程方式将 9 块背景设置为已设置填充的视图时,它们将被覆盖。反之亦然,如果您设置填充,它们会覆盖 9 补丁背景设置的内容。

不幸的是,在 XML 布局中无法确定这些操作的顺序。我认为从 TextView 中删除背景会有帮助:

android:background="@null"

Just wanted to add to DynamicMind's answer that the reason why you see spacing around your TextViews is padding in 9-patch backgrounds they use by default.

9-patch technology allows you to specify a content area which is, effectively, padding. That padding is used unless you set the view's padding explicitly. E.g., when you programmatically set a 9-patch background to a view which had paddings set, they are overridden. And vise-versa, if you set paddings they override what was set by 9-patch background.

Unfortunately, in the XML layout it's not possible to determine the order of these operations. I think just removing the background from your TextViews would help:

android:background="@null"
眼眸印温柔 2024-11-25 19:30:01
public class TopAlignedTextView extends TextView {

    public TopAlignedTextView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TopAlignedTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs);
        setIncludeFontPadding(false); //remove the font padding
        setGravity(getGravity() | Gravity.TOP);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        TextPaint textPaint = getPaint();
        textPaint.setColor(getCurrentTextColor());
        textPaint.drawableState = getDrawableState();
        canvas.save();

        //remove extra font padding
        int yOffset = getHeight() - getBaseline();
        canvas.translate(0, - yOffset / 2);

        if (getLayout() != null) {
            getLayout().draw(canvas);
        }
        canvas.restore();
    }
}
public class TopAlignedTextView extends TextView {

    public TopAlignedTextView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TopAlignedTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs);
        setIncludeFontPadding(false); //remove the font padding
        setGravity(getGravity() | Gravity.TOP);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        TextPaint textPaint = getPaint();
        textPaint.setColor(getCurrentTextColor());
        textPaint.drawableState = getDrawableState();
        canvas.save();

        //remove extra font padding
        int yOffset = getHeight() - getBaseline();
        canvas.translate(0, - yOffset / 2);

        if (getLayout() != null) {
            getLayout().draw(canvas);
        }
        canvas.restore();
    }
}
慵挽 2024-11-25 19:30:01

修改了this答案,以使用kotlin类并扩展AppCompatTextView,修剪垂直填充。

它允许设置android:fontFamily。为了提高性能,calculateTextParams() 方法从 onDraw() 中移出。未测试多行文本:

import android.content.Context
import android.graphics.Canvas
import android.graphics.Rect
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatTextView

class NoPaddingTextView : AppCompatTextView
{
  private val boundsRect = Rect()
  private val textParams = calculateTextParams()

  constructor(context : Context?)
  : super(context)

  constructor(context : Context?, attrs : AttributeSet?)
  : super(context, attrs)

  constructor(context : Context?, attrs : AttributeSet?, defStyleAttr : Int)
  : super(context, attrs, defStyleAttr)

  override fun onDraw(canvas : Canvas)
  {
    with(boundsRect) {
      paint.isAntiAlias = true
      paint.color = currentTextColor
      canvas.drawText(textParams,
                      -left.toFloat(),
                      (-top - bottom).toFloat(),
                      paint)
    }
  }

  override fun onMeasure(widthMeasureSpec : Int, heightMeasureSpec : Int)
  {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    calculateTextParams()
    setMeasuredDimension(boundsRect.width() + 1, -boundsRect.top + 1)
  }

  private fun calculateTextParams() : String
  {
    return text.toString()
    .also {text ->
      text.length.let {textLength ->
        paint.textSize = textSize
        paint.getTextBounds(text, 0, textLength, boundsRect)
        if(textLength == 0) boundsRect.right = boundsRect.left
      }
    }
  }
}

Modified this answer a little bit to use kotlin class and extend AppCompatTextView, trimming vertical padding.

It allows setting android:fontFamily. Method calculateTextParams() moved from onDraw() for performance. Not tested for multiple lines of text:

import android.content.Context
import android.graphics.Canvas
import android.graphics.Rect
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatTextView

class NoPaddingTextView : AppCompatTextView
{
  private val boundsRect = Rect()
  private val textParams = calculateTextParams()

  constructor(context : Context?)
  : super(context)

  constructor(context : Context?, attrs : AttributeSet?)
  : super(context, attrs)

  constructor(context : Context?, attrs : AttributeSet?, defStyleAttr : Int)
  : super(context, attrs, defStyleAttr)

  override fun onDraw(canvas : Canvas)
  {
    with(boundsRect) {
      paint.isAntiAlias = true
      paint.color = currentTextColor
      canvas.drawText(textParams,
                      -left.toFloat(),
                      (-top - bottom).toFloat(),
                      paint)
    }
  }

  override fun onMeasure(widthMeasureSpec : Int, heightMeasureSpec : Int)
  {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    calculateTextParams()
    setMeasuredDimension(boundsRect.width() + 1, -boundsRect.top + 1)
  }

  private fun calculateTextParams() : String
  {
    return text.toString()
    .also {text ->
      text.length.let {textLength ->
        paint.textSize = textSize
        paint.getTextBounds(text, 0, textLength, boundsRect)
        if(textLength == 0) boundsRect.right = boundsRect.left
      }
    }
  }
}
似梦非梦 2024-11-25 19:30:01

您定义了布局边距吗?
例如:

android:layout_marginTop="5dp"

否则,如果您的文本视图包含在 LinearLayout 或其他容器内,则该容器也具有填充或边距。

Have you defined a layout margin?
For example:

android:layout_marginTop="5dp"

Otherwise, if your text view is wrapped inside a LinearLayout or other container, then that cold have either padding or a margin too.

叹梦 2024-11-25 19:30:01
android:background="@android:drawable/editbox_background"

根据您想要的 editbox_background 更改它来使用它。
因为android提供了一些内置的后台,如上面的代码,根据您的要求进行选择。
也许它对你有帮助。

android:background="@android:drawable/editbox_background"

use it according to you change it that you want editbox_background.
because android provide some build in background like above code choose according to your requirement.
May be it is help full to you.

新雨望断虹 2024-11-25 19:30:01

在 LinearLayout 内部,默认填充可能是一个问题。尝试将其设置为 0dp。这对我有用。

Inside a LinearLayout the default padding might be an issue. Try setting it to 0dp. It worked for me.

暗藏城府 2024-11-25 19:30:01

TopAlignedTextView代码的答案TopAlignedTextView@GitHub

通过布局使用它:

<com.github.captain_miao.view.TopAlignedTextView
    android:id="@+id/text_a"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:text="@string/text_demo_a"
/>

在此处输入图像描述

The answer of TopAlignedTextView code:TopAlignedTextView@GitHub

use it by layout:

<com.github.captain_miao.view.TopAlignedTextView
    android:id="@+id/text_a"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:text="@string/text_demo_a"
/>

enter image description here

九局 2024-11-25 19:30:01

我解决这个问题的方法非常老套,但我设法通过将文本视图的高度设置为静态并摆弄它直到它几乎适合文本,使文本位于我想要的位置。就我而言,我使用的字体样式的高度为 64sp,因此我将 textview 的高度设置为 50sp,效果很好。我还必须将 foreground_gravity 设置为底部。

My way for fixing this is pretty hacky, but I managed to get the text to sit where I wanted by setting the height of the text view as static and fiddling with it until it just barely fit the text. In my case, the font style I was using had a height of 64sp so I set the height of my textview to 50sp and it worked okay. I also had to set foreground_gravity to bottom.

浅笑依然 2024-11-25 19:30:01
android:includeFontPadding="false"
android:includeFontPadding="false"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文