¿Puedo subrayar texto en un diseño de Android?

Respuestas:

1144

Se puede lograr si está utilizando un archivo xml de recursos de cadena , que admite etiquetas HTML como <b></b>, <i></i>y <u></u>.

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

Si desea subrayar algo del uso del código:

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
fuente
50
Hola, probé el código xml de recursos anterior y no funcionó. continuó mostrando el <u> subrayado </u> como texto sin formato
Jonathan el
44
Consulte también: android.text.Html.fromHtml () que devuelve un Spanned.
Mark Renouf
3
Debe escribirlo en el archivo strings.xml en sí, no haciéndolo con el botón Agregar. De lo contrario, obtendrá esto & lt; u & gt; en su archivo strings.xml y <u> subrayado </u> en su código
gdrt
3
He encontrado casos en los que el subyacente a través de las <u>etiquetas no funciona, por ejemplo, a veces, si está utilizando una fuente personalizada. Sin embargo, subyacente programáticamente UnderlineSpanaún no me ha fallado, por lo que lo recomendaría como la solución más confiable.
Giulio Piancastelli
26
No se mostrará en el editor, pero cuando inicies tu aplicación, aparecerá subrayada.
jean d'arme
534

Puedes probar con

textview.setPaintFlags(textview.getPaintFlags() |   Paint.UNDERLINE_TEXT_FLAG);
vado
fuente
1
Tal vez un punto menor, pero OP quería que esto se definiera en el archivo de diseño XML; de lo contrario, esta es una gran solución.
kwishnu
44
use esta solución si desea
borrarla
2
esta solución también se puede usar para un botón
Rudy Kurniawan
3
Tenga cuidado si usa fuentes personalizadas o similares, es posible que también necesite hacerlo | Paint.ANTI_ALIAS_FLAGo su texto se verá muy nítido. Esto se manifiesta en API más bajas la mayoría de las veces.
Martin Marconcini
44
En Kotlin:textView.paintFlags = textView.paintFlags or Paint.UNDERLINE_TEXT_FLAG
Albert Vila Calvo el
72

La respuesta "aceptada" anterior NO funciona (cuando intenta utilizar la cadena como textView.setText(Html.fromHtml(String.format(getString(...), ...))).

Como se indica en la documentación , debe escapar del corchete de apertura (codificado con la entidad html) de las etiquetas internas con &lt;, por ejemplo, el resultado debería verse así:

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

Luego, en su código, puede configurar el texto con:

TextView textView = (TextView) view.findViewById(R.id.textview);
textView.setText(Html.fromHtml(String.format(getString(R.string.my_string), ...)));
Ognyan
fuente
44
<u> subrayado aquí </u> funciona perfectamente. & lt; u> subrayar & lt; / u> no funcionó. Esto es para Android 2.2. Tal vez diferentes versiones lo interpretan de manera diferente.
user898763452
@autotravis, ¿cuál es para 2.2? No lo probé en versiones anteriores y será bastante desafortunado si las diferentes versiones lo manejan de manera diferente ... También al menos la documentación actual establece que debe ser escapado (el enlace está en la respuesta).
Ognyan
He probado <u> subrayado </u> en Android 2.3 y funciona. & lt; u> subrayar & lt; / u> no funciona para 2.3. Los documentos dicen "A veces es posible que desee crear un recurso de texto con estilo que también se use como una cadena de formato. Normalmente, esto no funcionará porque el método String.format (String, Object ...) eliminará toda la información de estilo desde la cadena. La solución a esto es escribir las etiquetas HTML con entidades escapadas, que luego se recuperan con fromHtml (String), una vez que se lleva a cabo el formateo ". Así que supongo que usarías el escape si lo ejecutas a través de ese método String.format (...).
user898763452
@autotravis sí, tienes razón. Lo uso con String.format (...). He editado mi respuesta, gracias por sus comentarios.
Ognyan
En 2.3 y 4.1 (solo los que probé hasta ahora) puede usar textView.setText (getText (R.string.text)) en lugar de tener que usar getString (), Html.fromHtml () y String.format ().
Roy Solberg
59

Contenido del archivo Strings.xml:

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

El archivo xml de diseño debe usar el recurso de cadena anterior con las siguientes propiedades de vista de texto, como se muestra a continuación:

<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
fuente
3
Asegúrese de editar el archivo de recursos de cadena dentro del XML real en lugar de dentro de la interfaz de usuario de edición auxiliar en Eclipse, ya que escapará de los <s.
Chris Rae
51

Para Button y TextView, esta es la forma más fácil:

Botón:

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

Vista de texto:

TextView textView = (TextView) findViewById(R.id.textview1);
textView.setPaintFlags(textView.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
awsleiman
fuente
Solución muy elegante. ¡Gracias!
Adrian
20

Solución de una línea

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

Es un poco tarde pero podría ser útil para alguien.

gprathour
fuente
20

En Kotlin se puede utilizar la función de extensión . Esto solo se puede usar desde el código, no desde xml.

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

Uso:

 tv_change_number.underline()
 tv_resend_otp.underline()
Asesino
fuente
13

echa un vistazo al estilo de botón clicable subrayado:

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

ingrese la descripción de la imagen aquí

Kirill Vashilo
fuente
La apariencia de Widget.AppCompat.Button.Borderless.Colored es mucho mejor que subrayar, sin embargo, como describió @Kiril Vashilo, puedes hacerlo de todos modos.
xarlymg89
11

El enfoque más reciente de dibujar texto subrayado es descrito por Romain Guy en medio con código fuente disponible en GitHub . Esta aplicación de muestra expone dos posibles implementaciones:

  • Una implementación basada en Path que requiere API level 19
  • Una implementación basada en la región que requiere API nivel 1

ingrese la descripción de la imagen aquí

Volodymyr
fuente
10

Sé que esta es una respuesta tardía, pero se me ocurrió una solución que funciona bastante bien ... Tomé la respuesta de Anthony Forloney por subrayar el texto en el código y creé una subclase de TextView que lo maneja por usted. Luego, puede usar la subclase en XML siempre que desee tener una TextView subrayada.

Aquí está la clase que creé:

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

Ahora ... cada vez que desee crear una vista de texto subrayada en XML, simplemente haga lo siguiente:

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

He agregado opciones adicionales en este fragmento de XML para mostrar que mi ejemplo funciona cambiando el color, el tamaño y el estilo del texto ...

¡Espero que esto ayude!

Justin
fuente
2
Si bien este ejemplo funciona, rápidamente me di cuenta de que si alguna vez desea tener un control adicional en XML, esto simplemente no funcionará ... He cambiado a una mejor solución que involucra los siguientes pasos: 1) Vista de texto de subclase 2) Agregar soporte para subrayar el texto mediante atributos personalizados para hacer el subrayado como se especifica anteriormente. La única diferencia es que solo ejecuta el código de subrayado si se establece el atributo personalizado.
Justin
10

Una forma más limpia en lugar del
textView.setPaintFlags(textView.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); método es usar textView.getPaint().setUnderlineText(true);

Y si luego necesita desactivar el subrayado para esa vista, como en una vista reutilizada en un RecyclerView, textView.getPaint().setUnderlineText(false);

jk7
fuente
7

Simplemente use el atributo en el archivo de recursos de cadena, por ejemplo

<string name="example"><u>Example</u></string>
Aditya S.
fuente
7

Usé este xml dibujable para crear un borde inferior y apliqué el dibujable como fondo a mi vista de texto

<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
fuente
Esta es la solución perfecta para todas las vistas subrayadas con colores personalizados. no falte el respeto al fondo transparente aquí, para Android 4 es obligatorio, su vista tendrá fondo negro sin él
Ivan Mitsura
5

Una solución simple y flexible en 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" />
usuario3786340
fuente
4

otra solución es crear una vista personalizada que extienda TextView como se muestra a continuación

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

}

y solo agregue a xml como se muestra a continuación

<yourpackage.UnderLineTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="underline text"
 />
has19
fuente
¡¡Increíble!! Pero el color del subrayado es gris, ¿cómo cambiarlo a negro o cualquier otro color?
OhhhThatVarun
3

Simplifiqué la respuesta 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
fuente
3

Creé este método para facilitar

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

Subrayar todo TextView

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

Subrayar alguna parte de TextView

setUnderLineText(tv, "some");

También admite niños 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);
            }
        }
    }

revise mi respuesta aquí para hacer que el texto subrayado sea cliqueable o subrayar varias partes de TextView

Khemraj
fuente
2

prueba este código

en XML

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

en codigo

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

¡Buena suerte!

Andrew.J
fuente
2
  1. Ir al archivo de recursos strings.xml
  2. Agregue una cadena en el archivo de recursos con una etiqueta de subrayado HTML cuando sea necesario.

strings.xml Ejemplo de subrayado HTML

  1. Llame al ID de recurso de cadena en su código Java de la siguiente manera:
sampleTextView.setText(R.string.sample_string);
  1. La salida debe tener la palabra "Stackoverflow" subrayada.

Además, el siguiente código no imprimirá el subrayado:

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

En su lugar, use el siguiente código para conservar el formato de texto enriquecido:

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

"Puede usar getString (int) o getText (int) para recuperar una cadena. GetText (int) conserva cualquier estilo de texto enriquecido aplicado a la cadena". Documentación de Android.

Consulte la documentación: https://developer.android.com/guide/topics/resources/string-resource.html

Espero que esto ayude.

Fahmi Eshaq
fuente
2

La respuesta más votada es correcta y más simple. Sin embargo, a veces puede encontrar que no funciona para algunas fuentes, sino para otras (qué problema acabo de encontrar cuando trato con chino).

La solución es no utilizar "WRAP_CONTENT" solo para su TextView, porque no hay espacio adicional para dibujar la línea. Puede establecer una altura fija en su TextView, o usar android: paddingVertical con WRAP_CONTENT.

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

Tenga en cuenta el símbolo de escape en el archivo xml

lynn8570
fuente
trabajó para mí con los símbolos de escape, ¡Gracias!
Badr el
1

Para hacer eso en Kotlin:

yourTextView.paint?.isUnderlineText = true

Canjear
fuente
0

Es bastante tarde para responder esto, pero supongamos que si alguien quiere obtener el texto dinámicamente, puede usar esta línea simple en su código Java que funciona:

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

Tuve un problema en el que estaba usando una fuente personalizada y el subrayado creado con el truco del archivo de recursos ( <u>Underlined text</u>) funcionó, pero Android logró transformar el subrayado en una especie de huelga.

Utilicé esta respuesta para dibujar un borde debajo de la vista de texto: https://stackoverflow.com/a/10732993/664449 . Obviamente, esto no funciona para texto subrayado parcial o texto multilínea.

Rick Pastoor
fuente