I am trying to reduce the line spacing in a TextView by setting a negative 'add' to TextView.setLineSpacing(). It works well except that the bottom line get truncated.
Main layout
<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" />
Main activity: (notice the
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");
}
}
This results in truncation at the bottom of the view (notice the 'g' at the bottom line):
It seems that the problem is related to incorrect layout measurement. If I set the TextView to
android:layout_height="fill_parent"
It does render properly:
Any idea how to fix it? I don't mind to have ugly workarounds if it helps. I also have access to FontForge and I can modify the font file if needed.
littleFluffyKittys answer is good but it didn't work on some devices if the linespacing was set through xml
I calculate the additional height needed by comparing the original height of the font with the height the textview calculates for a line. If the line height is smaller than the height of the font the diffrence is added one time.
This works down to at least API 10 propably lower (just not tested any lower)
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);
}
}
}