Можно ли подчеркнуть текст в макете Android?

Ответы:

1144

Этого можно достичь, если вы используете XML-файл строковых ресурсов , который поддерживает HTML-теги, такие как <b></b>, <i></i>и <u></u>.

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

Если вы хотите подчеркнуть что-то из кода, используйте:

TextView textView = (TextView) view.findViewById(R.id.textview);
SpannableString content = new SpannableString("Content");
content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
textView.setText(content);
Энтони Форлони
источник
50
Привет, я попробовал приведенный выше код ресурса XML, и он не работает. он продолжал отображать <u> подчеркивание </ u> в виде простого текста
Джонатан
4
Смотрите также: android.text.Html.fromHtml (), который возвращает Spanned.
Марк Ренуф
3
Вы должны напечатать его в самом файле strings.xml, не делая это кнопкой добавления. В противном случае вы получите это & ​​lt; u & gt; в вашем файле strings.xml и <u> подчеркивания </ u> в вашем коде
gdrt
3
Я сталкивался со случаями, когда нижележащие <u>теги не работают, например, иногда, если вы используете собственный шрифт. Тем не менее, программная UnderlineSpanоснова до сих пор на мне не сработала, поэтому я бы рекомендовал это как наиболее надежное решение.
Джулио Пьянкастелли
26
Он не будет отображаться в редакторе, но при запуске приложения - будет подчеркнут.
Жан д'Арм
534

Вы можете попробовать с

textview.setPaintFlags(textview.getPaintFlags() |   Paint.UNDERLINE_TEXT_FLAG);
Вадо
источник
1
Возможно, второстепенный вопрос, но OP хотел, чтобы это было определено в файле макета XML; в противном случае это отличное решение.
Квишну
4
используйте это решение, если хотите очистить его
Бобс
2
это решение можно использовать и для Баттона
Руди Курниаван
3
Будьте осторожны, если вы используете пользовательские шрифты или аналогичные, вам может понадобиться, | Paint.ANTI_ALIAS_FLAGили ваш текст будет выглядеть очень резким. Это проявляется в более низких API чаще, чем нет.
Мартин Маркончини,
4
В Котлине:textView.paintFlags = textView.paintFlags or Paint.UNDERLINE_TEXT_FLAG
Альберт Вила Кальво
72

«Принятый» ответ выше НЕ работает (когда вы пытаетесь использовать строку вроде textView.setText(Html.fromHtml(String.format(getString(...), ...))).

Как указано в документации, вы должны экранировать (в кодировке html-сущности) открывающую скобку внутренних тегов &lt;, например, результат должен выглядеть следующим образом:

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

Затем в вашем коде вы можете установить текст с помощью:

TextView textView = (TextView) view.findViewById(R.id.textview);
textView.setText(Html.fromHtml(String.format(getString(R.string.my_string), ...)));
Ognyan
источник
4
<u> подчеркнуто здесь </ u> работает отлично. & lt; u> подчеркивание & lt; / u> не работает. Это для Android 2.2. Возможно разные версии интерпретируют это по-разному.
user898763452
@autotravis какой для 2.2? Я не проверял его на более старых версиях, и будет весьма прискорбно, если разные версии будут обрабатывать его по-разному ... Также, по крайней мере, в текущей документации говорится, что его нужно экранировать (ссылка в ответе).
Огнян
Я протестировал <u> подчеркнутый </ u> на Android 2.3, и это работает. & lt; u> подчеркивание & lt; / u> не работает для 2.3. Документы говорят: «Иногда вам может понадобиться создать стилизованный текстовый ресурс, который также используется в качестве строки формата. Обычно это не работает, потому что метод String.format (String, Object ...) удалит всю информацию о стиле из строки. Обходным путем является написание HTML-тегов с экранированными сущностями, которые затем восстанавливаются с помощью fromHtml (String) после форматирования. " Поэтому я думаю, что вы бы использовали экранирование, если бы запускали его через этот метод String.format (...).
user898763452
@autotravis Да, вы правы. Я использую это с String.format (...). Я отредактировал свой ответ, спасибо за ваш отзыв.
Огнян
На 2.3 и 4.1 (только те, которые я пробовал до сих пор) вы можете просто использовать textView.setText (getText (R.string.text)) вместо необходимости использовать getString (), Html.fromHtml () и String.format ().
Рой Солберг
59

Содержимое файла Strings.xml:

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

Файл макета XML должен использовать указанный выше строковый ресурс со следующими свойствами textview, как показано ниже:

<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"
    />
Девендра Анураг
источник
3
Убедитесь, что вы редактируете файл строковых ресурсов внутри фактического XML, а не внутри пользовательского интерфейса вспомогательного редактирования в Eclipse, поскольку он будет экранировать <s.
Крис Рей
51

Для Button и TextView это самый простой способ:

Кнопка:

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);
awsleiman
источник
Очень элегантное решение. Спасибо!
Адриан
20

Одноканальное решение

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

Это немного поздно, но может быть полезно для кого-то.

gprathour
источник
20

В Kotlin можно использовать функцию расширения . Это можно использовать только из кода, а не из XML.

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

Применение:

 tv_change_number.underline()
 tv_resend_otp.underline()
киллер
источник
13

проверьте подчеркнутый стиль нажимаемой кнопки:

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

Результат:

введите описание изображения здесь

Кирилл Вашило
источник
Внешний вид Widget.AppCompat.Button.Borderless.Colored намного лучше, чем подчеркивание, однако, как описал @Kiril Vashilo, вы все равно можете это сделать.
xarlymg89
11

Самый последний подход к рисованию подчеркнутого текста описан Romain Guy на носителе с доступным исходным кодом на GitHub . В этом примере приложения представлены две возможные реализации:

  • Реализация на основе пути, которая требует уровня API 19
  • Региональная реализация, которая требует уровня API 1

введите описание изображения здесь

Владимир
источник
10

Я знаю, что это поздний ответ, но я нашел решение, которое работает довольно хорошо ... Я взял ответ от Энтони Форлони за подчеркивание текста в коде и создал подкласс TextView, который обрабатывает это для вас. Тогда вы можете просто использовать подкласс в XML всякий раз, когда вам нужен подчеркнутый TextView.

Вот класс, который я создал:

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

Теперь ... всякий раз, когда вы хотите создать подчеркнутое текстовое представление в XML, вы просто делаете следующее:

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

Я добавил дополнительные опции в этот фрагмент XML, чтобы показать, что мой пример работает с изменением цвета, размера и стиля текста ...

Надеюсь это поможет!

Джастин
источник
2
Хотя этот пример работает, я быстро понял, что если вы когда-нибудь захотите иметь дополнительный контроль в XML, чего просто не будет ... Я переключился на лучшее решение, включающее следующие шаги: 1) Текстовое представление подкласса 2) Добавить поддержку подчеркнуть текст с помощью пользовательских атрибутов, чтобы подчеркнуть, как указано выше. Единственное отличие состоит в том, что вы выполняете код подчеркивания, только если установлен пользовательский атрибут.
Джастин
10

Более чистый способ вместо
textView.setPaintFlags(textView.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); метода заключается в использовании textView.getPaint().setUnderlineText(true);

И если вам нужно позже отключить подчеркивание для этого представления, например, в повторно используемом представлении в RecyclerView, textView.getPaint().setUnderlineText(false);

jk7
источник
7

Просто используйте атрибут в файле строкового ресурса, например

<string name="example"><u>Example</u></string>
Адитья С.
источник
7

Я использовал этот XML-объект для рисования, чтобы создать нижнюю границу, и применил его в качестве фона для моего текстового представления.

<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>
Самуил
источник
Это идеальное решение для подчеркивания всех видов с использованием собственного цвета. не пренебрегайте прозрачным фоном здесь, для андроида 4 это обязательно, ваш взгляд будет иметь черный фон без него
Иван Мицура
5

Простое и гибкое решение в 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
источник
4

Другое решение заключается в создании пользовательского представления, расширяющего TextView, как показано ниже.

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

}

и просто добавьте в XML, как показано ниже

<yourpackage.UnderLineTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="underline text"
 />
has19
источник
Потрясающие!! Но цвет подчеркивания серый, как поменять его на черный или любой другой цвет?
OhhhThatVarun
3

Я упростил ответ Самуила :

<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
источник
3

Я создал этот метод для простоты

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

Подчеркните весь TextView

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

Подчеркните некоторую часть TextView

setUnderLineText(tv, "some");

Также поддержите потомки TextView, такие как 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);
            }
        }
    }

проверьте мой ответ здесь, чтобы сделать кликабельный подчеркнутый текст или подчеркнуть несколько частей TextView

Khemraj
источник
2

попробуй этот код

в XML

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

в коде

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

Удачи!

Andrew.J
источник
2
  1. Перейти к файлу ресурса strings.xml
  2. При необходимости добавьте строку в файл ресурсов с тегом подчеркивания HTML.

strings.xml Пример подчеркивания HTML

  1. Вызовите строковый идентификатор ресурса в вашем коде Java следующим образом:
sampleTextView.setText(R.string.sample_string);
  1. На выходе должно быть подчеркнуто слово «Stackoverflow».

Кроме того, следующий код не будет печатать подчеркивание:

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

Вместо этого используйте следующий код для сохранения расширенного текстового формата:

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

«Вы можете использовать getString (int) или getText (int) для извлечения строки. GetText (int) сохраняет любые стили расширенного текста, примененные к строке». Android документация.

Обратитесь к документации: https://developer.android.com/guide/topics/resources/string-resource.html

Надеюсь, это поможет.

Фахми Эшак
источник
2

Ответ с наибольшим количеством голосов является правильным и самым простым. Однако иногда вы можете обнаружить, что не работает с одним шрифтом, но работает с другими (с какой проблемой я столкнулся при работе с китайским).

Решение состоит в том, чтобы не использовать «WRAP_CONTENT» только для вашего TextView, потому что нет места для рисования линии. Вы можете установить фиксированную высоту для вашего TextView или использовать android: paddingVertical с WRAP_CONTENT.

Рэй Ли
источник
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>

Обратите внимание на символ Escape в файле XML

lynn8570
источник
работал для меня с символами побега, спасибо!
Бадр в
1

Для этого в Котлине:

yourTextView.paint?.isUnderlineText = true

Re'em
источник
0

Уже довольно поздно ответить на этот вопрос, но предположим, что если кто-то хочет получить текст динамически, он может использовать эту простую строку в своем коде Java, который работает:

 textView.setText(Html.fromHtml("<p><u>" + get_name + "</u></p>"));
Abby
источник
-2

У меня была проблема, когда я использую пользовательский шрифт и подчеркивание, созданное с помощью трюка файла ресурсов (<u>Underlined text</u> ), сработало, но Android удалось преобразовать подчеркивание в своего рода ударную впадину.

Я использовал этот ответ, чтобы нарисовать границу под видом текста: https://stackoverflow.com/a/10732993/664449 . Очевидно, что это не работает для частично подчеркнутого текста или многослойного текста.

Рик Пастур
источник