Can I underline text in an Android layout?

2019-01-01 06:43发布

问题:

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

回答1:

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);


回答2:

You can try with

textview.setPaintFlags(textview.getPaintFlags() |   Paint.UNDERLINE_TEXT_FLAG);


回答3:

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>underline&lt;/u>.</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), ...)));


回答4:

One line solution:

textview.setPaintFlags(textview.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);


回答5:

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\"
    />


回答6:

For Button and TextView this is the easiest way:

Button:

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

Textview:

textView = (Textview) view.findViewById(R.id.textview1);
textView.setPaintFlags(textView.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);


回答7:

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.



回答8:

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!



回答9:

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



回答10:

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



回答11:

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);



回答12:

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

<string name=\"example\"><u>Example</u></string>


回答13:

Damn, it is most simple to use

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

Underline whole TextView

setUnderLineText(tv, tv.getText().toString());

Underline some part of TextView

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);
            }
        }
    }

check my answer here to make clickable underline text or underline multiple parts of TextView



回答14:

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!



回答15:

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\" />


回答16:

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>


回答17:

  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.



回答18:

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>


回答19:

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()


回答20:

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\"
 />


回答21:

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.