如何减少TextView行间距

use*_*880 7 fonts android truetype textview

我试图通过设置TextView.setLineSpacing()的否定'添加'来减少TextView中的行间距.除了底线被截断之外,它运行良好.

主要布局

<TextView
    android:id="@+id/text_view"
    android:padding="dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    tools:context=".MainActivity" />
Run Code Online (Sandbox Code Playgroud)

主要活动:(注意

package com.font_test;

import android.app.Activity;
import android.graphics.Typeface;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Typeface typeface = Typeface.createFromAsset(getAssets(), "fonts/custom_fonts.ttf");
        final TextView tv = (TextView) findViewById(R.id.text_view);
        tv.setTypeface(typeface);
        tv.setTextSize(60);
        tv.setLineSpacing(-30f, 1f);  // *** -30 to reduce line spacing
        tv.setBackgroundColor(0x280000ff);
        tv.setText("gggkiiikkk" + "\n" + "gikgikgik" + "\n" + "kigkigkig");
    }
}
Run Code Online (Sandbox Code Playgroud)

这导致在视图底部截断(注意底线的'g'):

减少行间距会削减底线的

似乎问题与错误的布局测量有关.如果我将TextView设置为

 android:layout_height="fill_parent"
Run Code Online (Sandbox Code Playgroud)

它确实正确呈现:

使用'fill_parent'不会截断底线

知道怎么解决吗?如果它有帮助,我不介意有丑陋的变通方法.我也可以访问FontForge,如果需要我可以修改字体文件.

Zar*_*kka 10

littleFluffyKittys答案很好,但如果通过xml设置了linespacing,它在某些设备上不起作用

我通过比较字体的原始高度和textview为一条线计算的高度来计算所需的额外高度.如果行高小于字体的高度,则会添加一次diffrence.

这可以降低到至少API 10可降低(只是没有测试任何更低)

public class ReducedLineSpacingTextView extends TextView {

    public ReducedLineSpacingTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

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

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int truncatedHeight = getPaint().getFontMetricsInt(null) - getLineHeight();
        if (truncatedHeight > 0) {
            setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight() + truncatedHeight);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)


cot*_*aws 6

我遇到了同样的问题,但当我试图使用小于1的间距乘数时.

我创建了一个子类,TextView它自动修复了最后一行的截断,并且不需要在底部设置已知/固定的间距.

只需使用此类,您就可以正常使用它,您不需要应用任何额外的间距或修复.

public class ReducedLineSpacingTextView extends TextView {

    private boolean mNegativeLineSpacing = false;

    public ReducedLineSpacingTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

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

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (mNegativeLineSpacing) { // If you are only supporting Api Level 16 and up, you could use the getLineSpacingExtra() and getLineSpacingMultiplier() methods here to check for a less than 1 spacing instead.
            Layout layout = getLayout();
            int truncatedHeight = layout.getLineDescent(layout.getLineCount()-1);
            setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight() + truncatedHeight);
        }
    }

    @Override
    public void setLineSpacing(float add, float mult) {
        mNegativeLineSpacing = add < 0 || mult < 1;
        super.setLineSpacing(add, mult);
    }

}
Run Code Online (Sandbox Code Playgroud)


Jos*_*gia 0

如果填充不起作用,则边距应该可以发挥作用。如果仍然有问题,您可以随时将行间距值应用于视图的 onMeasure 方法。您必须为此创建一个自定义组件并扩展 onMeasure。