741

How can I define underlined text in an Android layout xml file?

Cœur
  • 32,421
  • 21
  • 173
  • 232
Janusz
  • 176,216
  • 111
  • 293
  • 365
  • Here i described best practise with example. see this Answer [link](https://stackoverflow.com/a/67087554/8265484) – Mayur Dabhi Apr 14 '21 at 07:49

26 Answers26

1229

It can be achieved if you are using a string resource xml file, which supports HTML tags like <b></b>, <i></i> and <u></u>.

<resources>
    <string name="your_string_here">This is an <u>underline</u>.</string>
</resources>

If you want to underline something from code use:

TextView textView = (TextView) view.findViewById(R.id.textview);
SpannableString content = new SpannableString("Content");
content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
textView.setText(content);
Max
  • 8,189
  • 4
  • 30
  • 45
Anthony Forloney
  • 84,001
  • 14
  • 111
  • 112
  • 51
    Hi, i tried the above resource xml code and it diddnt work. it continued to display the underline as a plain text – Jonathan Jul 01 '11 at 10:15
  • 4
    See also: android.text.Html.fromHtml( ) which returns a Spanned. – Mark Renouf Sep 07 '11 at 18:21
  • 3
    You should type it in strings.xml file itself, not doing it by add button. Otherwise you will get this <u> in your strings.xml file and underline in your code – gdrt Apr 01 '14 at 18:13
  • 3
    I have come across cases when underlying through `` tags does not work, e.g. sometimes if you are using a custom font. However, underlying programmatically by `UnderlineSpan` has yet to fail on me, so I would recommend it as the most reliable solution. – Giulio Piancastelli Apr 02 '14 at 18:17
  • Writing in the xml resource file did not work for me on Android SDK 4.0.3 . But Java code worked. Thank you – Nilesh May 16 '14 at 13:18
  • 30
    It won't show in editor, but when You start You app - it will be underlined. – jean d'arme Jul 01 '15 at 14:19
  • what if I want to have a bit of space between text and underline ? – Alex Jun 26 '16 at 04:24
  • FWIW, `text` worked for a string resource in an app running on Marshmallow. I entered it directly with a text editor, not a fancy text-escaping resource editor. – fadden Aug 10 '16 at 20:05
  • Don't use getString to fetch the string from your xml, use it directly e.g: tv.setText(R.string.your_html_string); Then it will work. – Gal Rom Jan 21 '18 at 13:19
  • @jonney Replace `` with `>`, then this should work. – hqzxzwb May 26 '18 at 09:48
  • For String resource, we need to wrap the text inside ` `` – Tuan Chau Dec 31 '19 at 07:25
564

You can try with

textview.setPaintFlags(textview.getPaintFlags() |   Paint.UNDERLINE_TEXT_FLAG);
Guykun
  • 2,701
  • 21
  • 27
vado
  • 5,649
  • 1
  • 10
  • 2
73

The "accepted" answer above does NOT work (when you try to use the string like textView.setText(Html.fromHtml(String.format(getString(...), ...))).

As stated in the documentations you must escape (html entity encoded) opening bracket of the inner tags with &lt;, e.g. result should look like:

<resource>
    <string name="your_string_here">This is an &lt;u&gt;underline&lt;/u&gt;.</string>
</resources>

Then in your code you can set the text with:

TextView textView = (TextView) view.findViewById(R.id.textview);
textView.setText(Html.fromHtml(String.format(getString(R.string.my_string), ...)));
Ismail Shaikh
  • 380
  • 3
  • 11
Ognyan
  • 12,916
  • 4
  • 61
  • 73
  • 5
    underlined here works perfectly. <u>underline</u> did not work. This is for Android 2.2. Maybe different versions interpret it differently. – user898763452 May 14 '12 at 01:13
  • @autotravis which one is for 2.2? I did not tested it on older versions and it will be quite unfortunate if different versions handle it differently... Also at least current documentation states that it have to be escaped (link is in the answer). – Ognyan May 18 '12 at 08:07
  • I've tested underlined on android 2.3 and it works. <u>underline</u> does not work for 2.3. The docs say "Sometimes you may want to create a styled text resource that is also used as a format string. Normally, this won't work because the String.format(String, Object...) method will strip all the style information from the string. The work-around to this is to write the HTML tags with escaped entities, which are then recovered with fromHtml(String), after the formatting takes place." So I guess you would use the escaping if you run it through that String.format(...) method. – user898763452 May 19 '12 at 19:07
  • @autotravis yes, you are correct. I use it with String.format(...). I've edited my answer, thank you for your feedback. – Ognyan May 22 '12 at 14:08
  • On 2.3 and 4.1 (only ones I tried so far) you can just use textView.setText(getText(R.string.text)) instead of having to use getString(), Html.fromHtml() and String.format(). – Roy Solberg Jul 24 '12 at 07:50
67

Strings.xml file content:

<resource>
     <string name="my_text">This is an <u>underline</u>.</string> 
</resources> 

Layout xml file shold use the above string resource with below properties of textview, as shown below:

<TextView 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:text="@string/my_text"

    android:selectAllOnFocus="false"
    android:linksClickable="false"
    android:autoLink="all"
    />
ZooMagic
  • 497
  • 6
  • 12
Devendra Anurag
  • 687
  • 5
  • 2
  • 3
    Make sure you edit the string resource file inside the actual XML rather than inside the helper editing UI in Eclipse, at it will escape the – Chris Rae Jan 23 '13 at 22:04
63

For Button and TextView this is the easiest way:

Button:

Button button = (Button) findViewById(R.id.btton1);
button.setPaintFlags(button.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);

Textview:

TextView textView = (TextView) findViewById(R.id.textview1);
textView.setPaintFlags(textView.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
Offboard
  • 29
  • 5
awsleiman
  • 1,609
  • 19
  • 14
32

In Kotlin extension function can be used. This can only be used from code, not xml.

fun TextView.underline() {
    paintFlags = paintFlags or Paint.UNDERLINE_TEXT_FLAG
}

Usage:

 tv_change_number.underline()
 tv_resend_otp.underline()
Jemshit Iskenderov
  • 7,417
  • 5
  • 48
  • 91
Killer
  • 3,574
  • 6
  • 35
  • 51
21

One line solution

myTextView.setText(Html.fromHtml("<p><u>I am Underlined text</u></p>"));

It is bit late but could be useful for someone.

gprathour
  • 13,193
  • 5
  • 56
  • 85
17

check out the underscored clickable button style:

<TextView
    android:id="@+id/btn_some_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/btn_add_contact"
    android:textAllCaps="false"
    android:textColor="#57a0d4"
    style="@style/Widget.AppCompat.Button.Borderless.Colored" />

strings.xml:

<string name="btn_add_contact"><u>Add new contact</u></string>

Result:

enter image description here

Vishal Yadav
  • 3,351
  • 3
  • 20
  • 40
Kirill Vashilo
  • 1,279
  • 15
  • 26
  • The look and feel of Widget.AppCompat.Button.Borderless.Colored is much better than underlining, however, as @Kiril Vashilo described, you can do it anyway. – xarlymg89 Mar 22 '18 at 12:16
  • 1
    For this, this forces the text to be upper case, gives it a large border, and makes it larger than the default text. – Jeffrey Blattman Jul 09 '20 at 20:31
13

A cleaner way instead of the
textView.setPaintFlags(textView.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); method is to use textView.getPaint().setUnderlineText(true);

And if you need to later turn off underlining for that view, such as in a reused view in a RecyclerView, textView.getPaint().setUnderlineText(false);

jk7
  • 1,743
  • 1
  • 20
  • 28
12

To do that in Kotlin:

yourTextView.paint?.isUnderlineText = true

Muhammad Reda
  • 24,289
  • 12
  • 85
  • 99
Re'em
  • 1,311
  • 1
  • 17
  • 24
11

I know this is a late answer, but I came up with a solution that works pretty well... I took the answer from Anthony Forloney for underlining text in code and created a subclass of TextView that handles that for you. Then you can just use the subclass in XML whenever you want to have an underlined TextView.

Here is the class I created:

import android.content.Context;
import android.text.Editable;
import android.text.SpannableString;
import android.text.TextWatcher;
import android.text.style.UnderlineSpan;
import android.util.AttributeSet;
import android.widget.TextView;

/**
 * Created with IntelliJ IDEA.
 * User: Justin
 * Date: 9/11/13
 * Time: 1:10 AM
 */
public class UnderlineTextView extends TextView
{
    private boolean m_modifyingText = false;

    public UnderlineTextView(Context context)
    {
        super(context);
        init();
    }

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

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

    private void init()
    {
        addTextChangedListener(new TextWatcher()
        {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after)
            {
                //Do nothing here... we don't care
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count)
            {
                //Do nothing here... we don't care
            }

            @Override
            public void afterTextChanged(Editable s)
            {
                if (m_modifyingText)
                    return;

                underlineText();
            }
        });

        underlineText();
    }

    private void underlineText()
    {
        if (m_modifyingText)
            return;

        m_modifyingText = true;

        SpannableString content = new SpannableString(getText());
        content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
        setText(content);

        m_modifyingText = false;
    }
}

Now... whenever you want to create an underlined textview in XML, you just do the following:

<com.your.package.name.UnderlineTextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:gravity="center"
    android:text="This text is underlined"
    android:textColor="@color/blue_light"
    android:textSize="12sp"
    android:textStyle="italic"/>

I have added additional options in this XML snippet to show that my example works with changing the text color, size, and style...

Hope this helps!

Justin
  • 6,344
  • 6
  • 35
  • 34
  • 2
    While this example works, I quickly realized that if you ever want to have additional control in XML that this just won't do... I have switched to a better solution that involves the following steps: 1) Subclass textview 2) Add support to underline the text via custom attributes to do the underlining as specified above. The only difference is that you only execute the underline code if the custom attribute is set. – Justin Mar 14 '14 at 20:18
11

The most recent approach of drawing underlined text is described by Romain Guy on medium with available source code on GitHub. This sample application exposes two possible implementations:

  • A Path-based implementation that requires API level 19
  • A Region-based implementation that requires API level 1

enter image description here

Volodymyr
  • 5,789
  • 4
  • 52
  • 78
7

I used this xml drawable to create a bottom-border and applied the drawable as the background to my textview

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle" >
            <solid android:color="@android:color/transparent" />
        </shape>
    </item>

    <item android:top="-5dp" android:right="-5dp" android:left="-5dp">
        <shape>
            <solid android:color="@android:color/transparent" />
            <stroke
                    android:width="1.5dp"
                    android:color="@color/pure_white" />
        </shape>
    </item>
</layer-list>
Darush
  • 9,625
  • 7
  • 53
  • 53
Samuel
  • 71
  • 1
  • 3
  • this is the perfect solution for all view underline with custom color. do not disrespect the transparent background here, for android 4 it is required, your view will have black background w/o it – Ivan Mitsura May 31 '18 at 20:45
7

Just use the attribute in string resource file e.g.

<string name="example"><u>Example</u></string>
Aditya Sonel
  • 2,619
  • 1
  • 21
  • 32
6

A simple and flexible solution in xml:

<View
  android:layout_width="match_parent"
  android:layout_height="3sp"
  android:layout_alignLeft="@+id/your_text_view_need_underline"
  android:layout_alignRight="@+id/your_text_view_need_underline"
  android:layout_below="@+id/your_text_view_need_underline"
  android:background="@color/your_color" />
user3786340
  • 111
  • 1
  • 6
6

Most Easy Way

TextView tv = findViewById(R.id.tv);
tv.setText("some text");
setUnderLineText(tv, "some");

Also support TextView childs like EditText, Button, Checkbox

public void setUnderLineText(TextView tv, String textToUnderLine) {
        String tvt = tv.getText().toString();
        int ofe = tvt.indexOf(textToUnderLine, 0);

        UnderlineSpan underlineSpan = new UnderlineSpan();
        SpannableString wordToSpan = new SpannableString(tv.getText());
        for (int ofs = 0; ofs < tvt.length() && ofe != -1; ofs = ofe + 1) {
            ofe = tvt.indexOf(textToUnderLine, ofs);
            if (ofe == -1)
                break;
            else {
                wordToSpan.setSpan(underlineSpan, ofe, ofe + textToUnderLine.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                tv.setText(wordToSpan, TextView.BufferType.SPANNABLE);
            }
        }
    }

If you want

- Clickable underline text?

- Underline multiple parts of TextView?

Then Check This Answer

Khemraj Sharma
  • 46,529
  • 18
  • 168
  • 182
5

I simplified Samuel's answer:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!--https://stackoverflow.com/a/40706098/4726718-->
    <item
        android:left="-5dp"
        android:right="-5dp"
        android:top="-5dp">
        <shape>
            <stroke
                android:width="1.5dp"
                android:color="@color/colorAccent" />
        </shape>
    </item>
</layer-list>
Darush
  • 9,625
  • 7
  • 53
  • 53
4

another solution is to a create a custom view that extend TextView as shown below

public class UnderLineTextView extends TextView {

    public UnderLineTextView(Context context) {
        super(context);
        this.setPaintFlags(Paint.UNDERLINE_TEXT_FLAG);
    }

    public UnderLineTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.setPaintFlags(Paint.UNDERLINE_TEXT_FLAG);
    }

}

and just add to xml as shown below

<yourpackage.UnderLineTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="underline text"
 />
has19
  • 997
  • 12
  • 25
3

try this code

in XML

<resource>
 <string name="my_text"><![CDATA[This is an <u>underline</u>]]></string> 
</resources> 

in Code

TextView textView = (TextView) view.findViewById(R.id.textview);
textView.setText(Html.fromHtml(getString(R.string.my_text)));

Good Luck!

Pragnesh Ghoda シ
  • 8,098
  • 3
  • 23
  • 39
Andrew.J
  • 49
  • 1
3

If you want to achieve this in XML, declare your string in resource and put that resource value into underline tag (<u></u>) of HTML. in TextView, add

android:text="@string/your_text_reference"

And in string resource value,

<string name="your_text_reference"><u>Underline me</u></string>

If you want to achieve this programmatically, for Kotlin use

textView.paintFlags = textView.paintFlags or Paint.UNDERLINE_TEXT_FLAG

or,

textView.text = Html.fromHtml("<p><u>Underline me</u></p>")
2
  1. Go to strings.xml resource file
  2. Add a string in the resource file with an HTML underline tag where necessary.

strings.xml HTML underline sample

  1. Call the string resource ID in your Java code as following:
sampleTextView.setText(R.string.sample_string);
  1. The output should have the word "Stackoverflow" underlined.

Furthermore, the following code will not print the underline:

String sampleString = getString(R.string.sample_string);
sampleTextView.setText(sampleString);

Instead, use the following code to retain rich text format:

CharSequence sampleString = getText(R.string.sample_string);
sampleTextView.setText(sampleString);

"You can use either getString(int) or getText(int) to retrieve a string. getText(int) retains any rich text styling applied to the string." Android documentation.

Refer to the documentation: https://developer.android.com/guide/topics/resources/string-resource.html

I hope this helps.

hqzxzwb
  • 4,080
  • 1
  • 10
  • 15
Fahmi Eshaq
  • 75
  • 2
  • 8
2

The top voted answer is right and simplest. However, sometimes you may find that not working for some font, but working for others.(Which problem I just came across when dealing with Chinese.)

Solution is do not use "WRAP_CONTENT" only for your TextView, cause there is no extra space for drawing the line. You may set fixed height to your TextView, or use android:paddingVertical with WRAP_CONTENT.

Ray Lee
  • 51
  • 5
1
HtmlCompat.fromHtml(
                    String.format(context.getString(R.string.set_target_with_underline)),
                    HtmlCompat.FROM_HTML_MODE_LEGACY)
<string name="set_target_with_underline">&lt;u>Set Target&lt;u> </string>

Note the Escape symbol in xml file

lynn8570
  • 1,657
  • 1
  • 13
  • 24
1

Very compact, kotlin version:

tvTitle.apply { 
    text = "foobar"
    paint?.isUnderlineText = true
}
Makalele
  • 6,691
  • 4
  • 49
  • 75
  • How is this answer any different from this [answer](https://stackoverflow.com/a/61040059/6782707) posted on April 5? – Edric Sep 17 '20 at 10:09
0

Its quite late to answer this but suppose if anyone wants to get the text dynamically then they can use this simple one line in their java code which works:

 textView.setText(Html.fromHtml("<p><u>" + get_name + "</u></p>"));
abby
  • 101
  • 2
  • 10
-2

I had a problem where I'm using a custom font and the underline created with the resource file trick (<u>Underlined text</u>) did work but Android managed to transform the underline to a sort of strike trough.

I used this answer to draw a border below the textview myself: https://stackoverflow.com/a/10732993/664449. Obviously this doesn't work for partial underlined text or multilined text.

Community
  • 1
  • 1
Rick Pastoor
  • 3,568
  • 1
  • 18
  • 24