Anne Droid
Anne Droid

Reputation: 3191

Individual line spacing for each line

Is it possible to define individual line spacings for each text line of a TextView?

Example:

TextView tv = new TextView(context);
tv.setText("line1\nline2\nline3");

The method setLineSpacing(float add, float mult) defines the line spacings for all text lines of the TextView. I would like to define another line spacing between line1 and line2 and a different line spacing between line2 and line3.

Any ideas how to do this ?

Does a spannable provide a solution ?

Upvotes: 10

Views: 11057

Answers (7)

grebulon
grebulon

Reputation: 7972

Android 10 (API 29) added LineHeightSpan.Standard to set an absolute line height. If you need backward compatibility, use the following implementation which I based on LineHeightSpan.Standard:

private static class AbsoluteHeightSpan implements LineHeightSpan {
    private final int _height;

    AbsoluteHeightSpan(int height) {
        _height = height;
    }

    @Override
    public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v, FontMetricsInt fm) {
        final int originHeight = fm.descent - fm.ascent;
        // If original height is not positive, do nothing
        if (originHeight <= 0)
            return;
        final float ratio = _height * 1.0f / originHeight;
        fm.descent = Math.round(fm.descent * ratio);
        fm.ascent = fm.descent - _height;
    }
}

Upvotes: 3

P1NG2WIN
P1NG2WIN

Reputation: 864

I did it via AbsoluteSizeSpan. Kotlin Extensions for add space between text in dip

Usage

buildSpannedString { 
    append("smth")
    spaceInDip(16)
    append("smth2")
}

Code

public fun SpannableStringBuilder.sizeInDip(
    size: Int,
    builderAction: SpannableStringBuilder.() -> Unit
): SpannableStringBuilder = inSpans(
    AbsoluteSizeSpan(size, true),
    builderAction = builderAction
)

public fun SpannableStringBuilder.spaceInDip(
    size: Int
): SpannableStringBuilder = sizeInDip(
    size = size,
    builderAction = {
        appendLine()
        sizeInDip(size) { appendLine() }
    }
)

Upvotes: 0

1c982d
1c982d

Reputation: 474

Recently I'm faced with a similar problem. I use a string resource from string.xml and display it in a dialog. I solve my issue by using <font> tag inside <string> and specify a font size for \n in it. The first \n is simply a line break, and the second is a new empty line, with height specified by <font size="YOUR_SIZE_FOR_THE_LINE"></font>.

Sample code:

    <string name="specification_msg"><b>1 Quick Action</b>
        \nQuick-Action is a small window which is supposed to be fast so it can offer you a convenient way of recording income and expenditure.
        <font size="4">\n\n</font><b>︎︎1.1 Brief Mode</b>
        \nDate and time will be hidden in window and set to current time. If you scarcely adjust them, turning on this feature will give you a cleaner view.
        <!-- Other lines -->
    </string>

Screenshot: Screenshot of TextView inside AlertDialog

enter image description here

(The line spaces are originally designed for Chinese characters, so the difference may seem less apparent in English.)

I know it's a dirty method but it can sometimes help...

Upvotes: 0

Manmohan Pal
Manmohan Pal

Reputation: 1577

Try this:

android:lineSpacingMultiplier = "3"

Line spacing can also be in decimal format.

Upvotes: -3

Joe
Joe

Reputation: 14059

Yes, you can do it by utilizing the LineHeightSpan interface. Here's a quick and dirty sample code on how to do this:

public class MyActivity extends Activity {

    private static class MySpan implements LineHeightSpan {
        private final int height;

        MySpan(int height) {
            this.height = height;
        }

        @Override
        public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v,
                FontMetricsInt fm) {
            fm.bottom += height;
            fm.descent += height;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        final TextView tv = new TextView(this);
        setContentView(tv);

        tv.setText("Lines:\n", BufferType.EDITABLE);
        appendLine(tv.getEditableText(), "Line 1 = 40\n", 40);
        appendLine(tv.getEditableText(), "Line 2 = 30\n", 30);
        appendLine(tv.getEditableText(), "Line 3 = 20\n", 20);
        appendLine(tv.getEditableText(), "Line 4 = 10\n", 10);
    }

    private void appendLine(Editable text, String string, int height) {
        final int start = text.length();
        text.append(string);
        final int end = text.length();
        text.setSpan(new MySpan(height), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }

}

Upvotes: 19

MBMJ
MBMJ

Reputation: 5431

Its not possible.This technique is use in c ,c++.What you use inside setText(),it shows the whole text you write .

Upvotes: -3

Akilan
Akilan

Reputation: 1717

you can do these kind of specific styles to the textview using Html. Try this example,

tv.setText(Html.fromHtml("<h2>Text1</h2><br><p>Text2</p>"));

Different kind of tags allowed here are,

<a href="...">
<b>
<big>
<blockquote>
<br>
<cite>
<dfn>
<div align="...">
<em>
<font size="..." color="..." face="...">
<h1>
<h2>
<h3>
<h4>
<h5>
<h6>
<i>
<img src="...">
<p>
<small>
<strike>
<strong>
<sub>
<sup>
<tt>
<u>

Upvotes: 1

Related Questions