我试图通过在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" />
主要活动:(注意
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");
}
}
这导致在视图底部截断(注意底线的'g'):
似乎问题与错误的布局测量有关。如果我将TextView设置为
android:layout_height="fill_parent"
它确实正确渲染:
知道怎么解决吗?如果它有帮助,我不介意有丑陋的变通方法。我也可以访问FontForge,如果需要,我可以修改字体文件。
答案 0 :(得分:9)
littleFluffyKittys答案很好,但如果通过xml设置了linepacing,它在某些设备上无效
我通过比较字体的原始高度和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);
}
}
}
答案 1 :(得分: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);
}
}
答案 2 :(得分:1)
尼斯! 这将成为工作,但在任何有变量的地方放置常量值绝不是一个好主意。您可以使用lineSpacing值以dinamyc方式将它们添加到onMeasure方法。 请注意,此值始终可通过“getLineSpacingExtra()”和“getLineSpacingMultiplier()”获得。或者甚至更容易获得两者的总和值:“getLineHeight()”。
虽然我觉得这个值应该包含在onMeasure方法中,但您可以随时测量所需的确切高度,然后进行简单的检查:
final int measuredHeight = getMeasuredHeight();
if (measuredHeight < neededHeight) {
setMeasuredDimension(getMeasuredWidth, neededHeight);
}
最后一件事,您不需要在分离的属性中传递上下文。如果您看一下构造函数,那么上下文已经存在。如果你需要组件的代码,你可以使用“getContext()”。
希望它有所帮助。
答案 3 :(得分:1)
使用此选项可减少文本视图中的行间距 **
机器人:lineSpacingMultiplier = “0.8”
**
答案 4 :(得分:0)
只需将paddingBottom添加到TextView xml的声明中,选择一个产生良好结果的值。并因此设置其他填充(顶部,让和右)的值。这应该可以解决您的问题
答案 5 :(得分:0)
如果填充不起作用,则边距应该完成。如果仍有问题,可以始终将行间距值应用于视图的onMeasure方法。您必须为此创建custom component并扩展onMeasure。
答案 6 :(得分:0)
这是我根据Jose的答案做的,它似乎有效。我对布局机制错综复杂不太熟悉。这段代码安全吗?有什么问题吗?
布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.font_test.MyTextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
tools:context=".MainActivity" />
</RelativeLayout>
添加了自定义TextView,将垂直高度扩展了N个像素:
package com.font_test;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.TextView;
public class MyTextView extends TextView {
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// TODO: provide an API to set extra bottom pixels (50 in this example)
setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight() + 50);
}
}
结果文本视图渲染没有在底部截断: