Posso sublinhar o texto em um layout do Android?

Respostas:

1143

Isso pode ser alcançado se você estiver usando um arquivo xml de recurso de sequência , que suporta tags HTML como <b></b>, <i></i>e <u></u>.

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

Se você quiser sublinhar algo do código, 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);
Anthony Forloney
fonte
49
Oi, eu tentei o código xml de recurso acima e ele não funcionou. continuou a exibir o <u> sublinhado </ u> como um texto simples
Jonathan
4
Consulte também: android.text.Html.fromHtml () que retorna um Spanned.
Mark Renouf
3
Você deve digitá-lo no próprio arquivo strings.xml, não usando o botão Adicionar. Caso contrário, você receberá este & lt; u & gt; no seu arquivo strings.xml e <u> sublinhado </ u> em seu código
GDRT
3
Me deparei com casos em que as <u>tags subjacentes não funcionam, por exemplo, às vezes, se você estiver usando uma fonte personalizada. No entanto, subjacente programaticamente por UnderlineSpanainda não falhou comigo, então eu recomendaria como a solução mais confiável.
Giulio Piancastelli
26
Não será exibido no editor, mas quando você iniciar o aplicativo, ele será sublinhado.
Jean d'arme
533

Você pode tentar com

textview.setPaintFlags(textview.getPaintFlags() |   Paint.UNDERLINE_TEXT_FLAG);
vado
fonte
1
Talvez um ponto secundário, mas o OP queria isso definido no arquivo de layout XML; caso contrário, esta é uma ótima solução.
Kwishnu
4
utilizar esta solução se você quiser limpá-la
Bobs
2
esta solução pode ser utilizada para um botão demasiado
Rudy Kurniawan
3
Cuidado se você usar fontes personalizadas ou semelhante, talvez seja necessário | Paint.ANTI_ALIAS_FLAGtambém ou o texto ficará muito nítido. Isso se manifesta em APIs mais baixas com mais frequência do que não.
Martin Marconcini
4
Em Kotlin:textView.paintFlags = textView.paintFlags or Paint.UNDERLINE_TEXT_FLAG
Albert Vila Calvo
72

A resposta "aceita" acima NÃO funciona (quando você tenta usar a string como textView.setText(Html.fromHtml(String.format(getString(...), ...))).

Conforme declarado nas documentações, você deve escapar do colchete de abertura (tags codificadas por entidades html) das tags internas com &lt;, por exemplo, o resultado deve se parecer com:

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

Em seu código, você pode definir o texto com:

TextView textView = (TextView) view.findViewById(R.id.textview);
textView.setText(Html.fromHtml(String.format(getString(R.string.my_string), ...)));
Ognyan
fonte
4
<u> sublinhado aqui </u> funciona perfeitamente. & lt; u> sublinhado & lt; / u> não funcionou. Isto é para o Android 2.2. Talvez versões diferentes o interpretem de maneira diferente.
User898763452
@autotravis qual é o 2.2? Eu não o testei em versões mais antigas e será uma pena que versões diferentes o manejem de maneira diferente ... Além disso, pelo menos a documentação atual indica que ele precisa ser escapado (o link está na resposta).
Ognyan
Eu testei o <u> sublinhado </u> no Android 2.3 e funciona. & lt; u> sublinhado & lt; / u> não funciona para 2.3. Os documentos dizem "Às vezes, você pode criar um recurso de texto com estilo que também é usado como uma sequência de formato. Normalmente, isso não funciona porque o método String.format (String, Object ...) retira todas as informações de estilo. A solução para isso é escrever as tags HTML com entidades de escape, que são recuperadas com fromHtml (String), após a formatação. " Então, acho que você usaria o escape se o executasse através desse método String.format (...).
User898763452
@autotravis sim, você está correto. Eu o uso com String.format (...). Editei minha resposta, obrigado por seus comentários.
Ognyan
No 2.3 e 4.1 (apenas os que eu tentei até agora), você pode apenas usar textView.setText (getText (R.string.text)) em vez de usar getString (), Html.fromHtml () e String.format ().
Roy Solberg
59

Conteúdo do arquivo Strings.xml:

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

O arquivo xml de layout deve usar o recurso de string acima com as propriedades abaixo do textview, conforme mostrado abaixo:

<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"
    />
Devendra Anurag
fonte
3
Certifique-se de editar o arquivo de recursos da cadeia de caracteres dentro do XML real, e não dentro da interface do usuário de edição auxiliar no Eclipse, pois ele escapará dos <s.
Chris Rae
51

Para Button e TextView, esta é a maneira mais fácil:

Botão:

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
fonte
Solução muito elegante. Obrigado!
Adrian
20

Solução de uma linha

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

É um pouco tarde, mas pode ser útil para alguém.

gprathour
fonte
19

Na função de extensão Kotlin pode ser usada. Isso pode ser usado apenas a partir do código, não do xml.

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

Uso:

 tv_change_number.underline()
 tv_resend_otp.underline()
Assassino
fonte
13

confira o estilo de botão clicável sublinhado:

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

Resultado:

insira a descrição da imagem aqui

Kirill Vashilo
fonte
A aparência do Widget.AppCompat.Button.Borderless.Colored é muito melhor do que sublinhar, no entanto, como @Kiril Vashilo descreveu, você pode fazê-lo de qualquer maneira.
xarlymg89
11

A abordagem mais recente do desenho de texto sublinhado é descrita por Romain Guy no meio com o código fonte disponível no GitHub . Este aplicativo de exemplo expõe duas implementações possíveis:

  • Uma implementação baseada em caminho que requer o nível 19 da API
  • Uma implementação baseada na região que requer o nível 1 da API

insira a descrição da imagem aqui

Volodymyr
fonte
10

Eu sei que essa é uma resposta tardia, mas eu vim com uma solução que funciona muito bem ... Peguei a resposta de Anthony Forloney por sublinhar o texto no código e criei uma subclasse de TextView que lida com isso para você. Em seguida, você pode usar a subclasse em XML sempre que quiser ter um TextView sublinhado.

Aqui está a classe que eu criei:

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

Agora ... sempre que você quiser criar uma visualização de texto sublinhada em XML, faça o seguinte:

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

Adicionei opções adicionais neste snippet XML para mostrar que meu exemplo funciona com a alteração da cor, tamanho e estilo do texto ...

Espero que isto ajude!

Justin
fonte
2
Enquanto este exemplo funciona, percebi rapidamente que, se você quiser ter um controle adicional em XML, isso simplesmente não funcionará ... Eu mudei para uma solução melhor que envolve as seguintes etapas: 1) Subclasse textview 2) Adicione suporte para sublinhar o texto por meio de atributos personalizados para fazer o sublinhado, conforme especificado acima. A única diferença é que você só executa o código de sublinhado se o atributo personalizado estiver definido.
23414 Justin Just
10

Uma maneira mais limpa, em vez do
textView.setPaintFlags(textView.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); método, é usar textView.getPaint().setUnderlineText(true);

E se você precisar desativar posteriormente o sublinhado dessa exibição, como em uma exibição reutilizada em um RecyclerView, textView.getPaint().setUnderlineText(false);

jk7
fonte
7

Basta usar o atributo no arquivo de recursos da string, por exemplo

<string name="example"><u>Example</u></string>
adityasnl
fonte
7

Eu usei esse drawable xml para criar uma borda inferior e apliquei o drawable como plano de fundo ao meu 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>
Samuel
fonte
esta é a solução perfeita para todas as vistas sublinhadas com cores personalizadas. não desrespeitar o fundo transparente aqui, para o Android 4 é necessário, a sua visão terá fundo preto w / o que
Ivan Mitsura
5

Uma solução simples e flexível em 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
fonte
4

Outra solução é criar uma exibição personalizada que estenda o TextView, como mostrado abaixo

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

}

e basta adicionar ao xml como mostrado abaixo

<yourpackage.UnderLineTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="underline text"
 />
has19
fonte
Impressionante!! Mas a cor do sublinhado é cinza, como alterá-lo para preto ou qualquer outra cor?
OhhhThatVarun 12/08/19
3

Simplifiquei a resposta de Samuel :

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

Eu criei esse método para facilitar

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

Sublinhar todo o TextView

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

Sublinhe uma parte do TextView

setUnderLineText(tv, "some");

Também suporta childs TextView como 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);
            }
        }
    }

verifique minha resposta aqui para tornar o texto sublinhado clicável ou várias partes do TextView

Khemraj
fonte
2

tente este código

em XML

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

em código

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

Boa sorte!

Andrew.J
fonte
2
  1. Vá para o arquivo de recursos strings.xml
  2. Adicione uma sequência no arquivo de recurso com uma marca de sublinhado HTML, quando necessário.

exemplo de sublinhado HTML de strings.xml

  1. Chame o ID do recurso de sequência no seu código Java da seguinte maneira:
sampleTextView.setText(R.string.sample_string);
  1. A saída deve ter a palavra "Stackoverflow" sublinhada.

Além disso, o código a seguir não imprimirá o sublinhado:

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

Em vez disso, use o seguinte código para manter o formato rich text:

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

"Você pode usar getString (int) ou getText (int) para recuperar uma string. GetText (int) mantém qualquer estilo de rich text aplicado à string." Documentação do Android.

Consulte a documentação: https://developer.android.com/guide/topics/resources/string-resource.html

Eu espero que isso ajude.

Fahmi Eshaq
fonte
2

A resposta mais votada é correta e mais simples. No entanto, às vezes você pode achar que não está funcionando para algumas fontes, mas está funcionando para outras (que problema acabei de encontrar quando lida com chinês).

A solução é não usar "WRAP_CONTENT" apenas para o seu TextView, pois não há espaço extra para desenhar a linha. Você pode definir a altura fixa para o seu TextView ou usar android: paddingVertical com WRAP_CONTENT.

Ray Lee
fonte
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>

Observe o símbolo de escape no arquivo xml

lynn8570
fonte
trabalhou para mim com os símbolos de fuga, obrigado!
Badr Em
1

Para fazer isso em Kotlin:

yourTextView.paint?.isUnderlineText = true

Re'em
fonte
0

É muito tarde para responder isso, mas suponha que se alguém quiser obter o texto dinamicamente, poderá usar esta linha simples em seu código java que funciona:

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

Eu tive um problema em que estou usando uma fonte personalizada e o sublinhado criado com o arquivo de recurso trick ( <u>Underlined text</u>) funcionou, mas o Android conseguiu transformar o sublinhado em uma espécie de greve.

Eu mesmo usei esta resposta para desenhar uma borda abaixo da visualização de texto: https://stackoverflow.com/a/10732993/664449 . Obviamente, isso não funciona para texto parcial sublinhado ou texto multilinhado.

Rick Pastoor
fonte