簡體   English   中英

Android:TextView:刪除頂部和底部的間距和填充

[英]Android: TextView: Remove spacing and padding on top and bottom

當我有一個TextView在文本中有一個\n時,在右邊我有兩個singleLine TextView s,一個在另一個下面,中間沒有間距。 我為所有三個TextView設置了以下內容。

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

左邊的第一行TextView與右上角的TextView完美對齊。

左邊第二行TextView比右下第二行TextView高一點。

似乎在TextView的頂部和底部有某種隱藏的填充。 我怎樣才能刪除它?

setIncludeFontPadding (boolean includepad)

或者在XML中,這將是:

android:includeFontPadding="false"

設置TextView是否包含額外的頂部和底部填充,以便為超出正常上升和下降的重音騰出空間。 默認值為真。

我搜索了很多正確的答案,但沒有找到可以從TextView中完全刪除所有填充的答案,但最終在通過官方文檔后,解決了單行文本

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

將這兩行添加到TextView xml 就可以了。
第一個屬性刪除為重音保留的填充,第二個屬性刪除保留的間距以保持兩行文本之間的適當間距。

確保不要在多行 TextView 中添加lineSpacingExtra="0dp"因為它可能會使外觀笨拙

我感覺到你的痛苦。 我已經嘗試了上面的每個答案,包括將setIncludeFontPadding為 false,這對我沒有任何幫助。

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

雖然, layout_marginTop 上的layout_marginTop失敗了......呃。

你可以嘗試使用這個屬性(ConstraintLayout): layout_constraintBaseline_toBaselineOf

像這樣:

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

在此處輸入圖像描述

在此處輸入圖像描述

更新的 XML

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

如果您使用AppCompatTextView (或從API 28開始),您可以使用這兩個屬性的組合來刪除第一行的間距:

XML

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

科特林

text.firstBaselineToTopHeight = 0
text.includeFontPadding = false

添加 android:includeFontPadding="false" 看看是否有幫助。並使文本視圖大小與文本大小相同,而不是“包裝內容”。它肯定會工作。

我刪除了自定義視圖中的間距——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;
    }
}

這也讓我很惱火,我發現的答案是字體本身實際上有額外的空間,而不是 TextView。 這是相當惱人的,來自文檔發布背景,您對 Android 對排版元素的控制量有限。 我建議使用可能沒有此問題的自定義字體(例如 Bitstream Vera Sans,它已獲得再分發許可)。 不過,我不確定它是否確實如此。

由於我的要求是覆蓋現有的 textView 從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 個(即原件):

在此處輸入圖像描述

<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 的基線相同。

然而,這只修復了填充底部而不是頂部。

我認為這個問題可以這樣解決:

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

這些是結果:

截圖-1

截圖 3

盡管 rightLowerText 中的特殊字符行看起來比 leftText 的第二行高一點,但它們的基線仍然對齊。

簡單的方法有效:

setSingleLine();
setIncludeFontPadding(false);

如果它不起作用,請嘗試在該代碼上方添加此代碼:

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

如果您需要多行,也許您需要通過臨時單行 TextView(刪除填充之前和之后)精確計算填充頂部和底部的高度,然后使用負填充或一些帶有平移 Y 的幽靈布局應用降低高度結果。哈哈

唯一有效的是

android:lineSpacingExtra="-8dp"

您可能想嘗試將左側文本視圖的底部與第二個右側文本視圖的底部對齊。

據我所知,這是大多數小部件所固有的,並且手機制造商之間的“填充”量不同。 這個填充實際上是圖像邊框和 9 補丁圖像文件中的圖像之間的空白。

例如,在我的 Droid X 上,微調器小部件比按鈕獲得更多的空白,這使得當你有一個與按鈕內聯的微調器時看起來很尷尬,但在我妻子的手機上,相同的應用程序沒有同樣的問題,而且看起來很棒!

我唯一的建議是創建您自己的 9 個補丁文件並在您的應用程序中使用它們。

啊,Android的痛苦。

編輯:澄清填充與空白。

這個技巧對我有用(對於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>

使用約束布局作為你的根視圖,然后添加一個指南助手。

例子:

<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 值只是示例,它取決於您的需要。

您可以使用此處列出的一些技巧(負邊距、字體填充等)部分解決此問題,但您無法繞過字體本身的大小 [1]。 字體的每個“單元格”的固定高度必須足夠大,以容納所有語言中最高的字符。

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

解決方案是向您的設計師解釋這是字體的打包方式,並讓他們在設計中考慮到這一點。 當它被翻譯成其他語言時,現在不要把事情搞砸,以便在路上提交錯誤。

[1] 我想人們可以用壓縮的上升和下降來打包自己的字體。

這對我有用:

android:minHeight="0dp"

您可以嘗試使用此屬性(ConstraintLayout): layout_constraintBaseline_toBaselineOf

看到這個:

將 ImageView 與 EditText 水平對齊

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

一種解決方案是將 EditText 的默認背景更改為其他內容(或不更改任何內容,但 EditText 沒有背景可能是不可接受的)。 這可以通過設置 android:background XML 屬性來實現。

android:background="@drawable/myEditBackground"

當我有一個TextView帶有\\nTextView時,在右側,我有兩個singleLine TextView ,一個在另一個之下,並且兩者之間沒有間隔。 我為所有三個TextView設置了以下內容。

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

TextView的第一行與右上TextView完美TextView

左側TextView的第二行比右下方TextView的第二行高一點。

似乎在TextView的頂部和底部都有某種隱藏的填充。 我該如何刪除?

在您的 ImageView xml 中使用它

機器人:adjustViewBounds =“真”

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM