Puis-je souligner du texte dans une mise en page Android?

Réponses:

1144

Cela peut être réalisé si vous utilisez un fichier xml de ressource de chaîne , qui prend en charge les balises HTML comme <b></b>, <i></i>et <u></u>.

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

Si vous souhaitez souligner quelque chose de l'utilisation du code:

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
la source
50
Salut, j'ai essayé le code xml de ressource ci-dessus et cela n'a pas fonctionné. il a continué d'afficher le <u> souligné </u> sous forme de texte brut
Jonathan
4
Voir aussi: android.text.Html.fromHtml () qui retourne un Spanned.
Mark Renouf
3
Vous devez le taper dans le fichier strings.xml lui-même, sans le faire par le bouton ajouter. Sinon, vous obtiendrez ce & lt; u & gt; dans votre fichier strings.xml et <u> souligné </u> dans votre code
gdrt
3
J'ai rencontré des cas où le sous-jacent via des <u>balises ne fonctionne pas, par exemple parfois si vous utilisez une police personnalisée. Cependant, le sous-programme par défaut UnderlineSpann'a pas encore échoué sur moi, donc je le recommanderais comme la solution la plus fiable.
Giulio Piancastelli
26
Il ne s'affichera pas dans l'éditeur, mais lorsque vous lancerez votre application, il sera souligné.
jean d'arme
534

Vous pouvez essayer avec

textview.setPaintFlags(textview.getPaintFlags() |   Paint.UNDERLINE_TEXT_FLAG);
vado
la source
1
Peut-être un point mineur, mais OP voulait que cela soit défini dans un fichier de disposition XML; sinon, c'est une excellente solution.
kwishnu
4
utilisez cette solution si vous voulez l'effacer
Bobs
2
cette solution peut également être utilisée pour un bouton
Rudy Kurniawan
3
Attention si vous utilisez des polices personnalisées ou similaires, vous devrez peut-être | Paint.ANTI_ALIAS_FLAGaussi ou votre texte sera très net. Cela se manifeste le plus souvent dans les API inférieures.
Martin Marconcini
4
À Kotlin:textView.paintFlags = textView.paintFlags or Paint.UNDERLINE_TEXT_FLAG
Albert Vila Calvo
72

La réponse "acceptée" ci-dessus ne fonctionne PAS (lorsque vous essayez d'utiliser la chaîne comme textView.setText(Html.fromHtml(String.format(getString(...), ...))).

Comme indiqué dans les documentations, vous devez échapper (parenthèse html encodée) le crochet d'ouverture des balises internes avec &lt;, par exemple, le résultat devrait ressembler à:

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

Ensuite, dans votre code, vous pouvez définir le texte avec:

TextView textView = (TextView) view.findViewById(R.id.textview);
textView.setText(Html.fromHtml(String.format(getString(R.string.my_string), ...)));
Ognyan
la source
4
<u> souligné ici </u> fonctionne parfaitement. & lt; u> souligner & lt; / u> n'a pas fonctionné. C'est pour Android 2.2. Peut-être que différentes versions l'interprètent différemment.
user898763452
@autotravis lequel est pour 2.2? Je ne l'ai pas testé sur des versions plus anciennes et ce sera assez malheureux si différentes versions le gèrent différemment ... Aussi au moins la documentation actuelle précise qu'il faut l'échapper (lien dans la réponse).
Ognyan
J'ai testé <u> souligné </u> sur Android 2.3 et cela fonctionne. & lt; u> souligner & lt; / u> ne fonctionne pas pour 2.3. Les documents indiquent "Parfois, vous souhaiterez peut-être créer une ressource de texte de style qui est également utilisée comme chaîne de format. Normalement, cela ne fonctionnera pas car la méthode String.format (String, Object ...) supprimera toutes les informations de style à partir de la chaîne. La solution consiste à écrire les balises HTML avec des entités d'échappement, qui sont ensuite récupérées avec fromHtml (String), une fois la mise en forme effectuée. " Je suppose donc que vous utiliseriez l'échappement si vous l'exécutez via cette méthode String.format (...).
user898763452
@autotravis oui, vous avez raison. Je l'utilise avec String.format (...). J'ai édité ma réponse, merci pour vos commentaires.
Ognyan
Sur 2.3 et 4.1 (seuls ceux que j'ai essayés jusqu'à présent), vous pouvez simplement utiliser textView.setText (getText (R.string.text)) au lieu d'avoir à utiliser getString (), Html.fromHtml () et String.format ().
Roy Solberg
59

Contenu du fichier Strings.xml:

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

Le fichier xml de mise en page doit utiliser la ressource de chaîne ci-dessus avec les propriétés ci-dessous de textview, comme indiqué ci-dessous:

<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
la source
3
Assurez-vous de modifier le fichier de ressources de chaîne à l'intérieur du XML réel plutôt qu'à l'intérieur de l'interface utilisateur de modification d'aide dans Eclipse, car cela échappera aux <s.
Chris Rae
51

Pour Button et TextView, c'est la manière la plus simple:

Bouton:

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

Affichage:

TextView textView = (TextView) findViewById(R.id.textview1);
textView.setPaintFlags(textView.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
awsleiman
la source
Solution très élégante. Je vous remercie!
Adrian
20

Solution en une ligne

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

Il est un peu tard mais pourrait être utile à quelqu'un.

gprathour
la source
20

Dans Kotlin, la fonction d'extension peut être utilisée. Cela ne peut être utilisé qu'à partir du code, pas du xml.

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

Usage:

 tv_change_number.underline()
 tv_resend_otp.underline()
Tueur
la source
13

découvrez le style de bouton cliquable souligné:

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

Résultat:

entrez la description de l'image ici

Kirill Vashilo
la source
L'aspect et la convivialité de Widget.AppCompat.Button.Borderless.Colored est bien meilleur que de le souligner, cependant, comme @Kiril Vashilo l'a décrit, vous pouvez le faire quand même.
xarlymg89
11

L'approche la plus récente de dessiner du texte souligné est décrite par Romain Guy sur support avec le code source disponible sur GitHub . Cet exemple d'application expose deux implémentations possibles:

  • Une implémentation basée sur le chemin qui nécessite le niveau d'API 19
  • Une implémentation basée sur une région qui nécessite l'API niveau 1

entrez la description de l'image ici

Volodymyr
la source
10

Je sais que c'est une réponse tardive, mais j'ai trouvé une solution qui fonctionne assez bien ... J'ai pris la réponse d'Anthony Forloney pour souligner le texte dans le code et créé une sous-classe de TextView qui gère cela pour vous. Ensuite, vous pouvez simplement utiliser la sous-classe en XML chaque fois que vous souhaitez avoir un TextView souligné.

Voici la classe que j'ai créée:

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

Maintenant ... chaque fois que vous voulez créer une vue textuelle soulignée en XML, vous n'avez qu'à faire ce qui suit:

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

J'ai ajouté des options supplémentaires dans cet extrait XML pour montrer que mon exemple fonctionne avec la modification de la couleur, de la taille et du style du texte ...

J'espère que cela t'aides!

Justin
la source
2
Bien que cet exemple fonctionne, je me suis vite rendu compte que si jamais vous vouliez avoir un contrôle supplémentaire en XML, cela ne suffirait pas ... J'ai opté pour une meilleure solution qui implique les étapes suivantes: 1) Sous-classe textview 2) Ajouter un support pour souligner le texte via des attributs personnalisés pour faire le soulignement comme spécifié ci-dessus. La seule différence est que vous n'exécutez le code de soulignement que si l'attribut personnalisé est défini.
Justin
10

Une façon plus propre au lieu de la
textView.setPaintFlags(textView.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); méthode consiste à utiliser textView.getPaint().setUnderlineText(true);

Et si vous devez désactiver ultérieurement le soulignement pour cette vue, comme dans une vue réutilisée dans un RecyclerView, textView.getPaint().setUnderlineText(false);

jk7
la source
7

Utilisez simplement l'attribut dans le fichier de ressources de chaîne, par exemple

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

J'ai utilisé ce dessin xml pour créer une bordure inférieure et j'ai appliqué le dessin comme arrière-plan à mon affichage de texte

<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
la source
c'est la solution parfaite pour toutes les vues soulignées avec des couleurs personnalisées. ne manquez pas le fond transparent ici, pour android 4 c'est nécessaire, votre vue aura un fond noir sans
Ivan Mitsura
5

Une solution simple et 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" />
user3786340
la source
4

une autre solution consiste à créer une vue personnalisée qui étend TextView comme indiqué ci-dessous

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

}

et ajoutez simplement au xml comme indiqué ci-dessous

<yourpackage.UnderLineTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="underline text"
 />
has19
la source
Impressionnant!! Mais la couleur du soulignement est le gris comment le changer en noir ou en toute autre couleur?
OhhhThatVarun
3

J'ai simplifié la réponse 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
la source
3

J'ai créé cette méthode pour plus de facilité

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

Souligner TextView entier

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

Soulignez une partie de TextView

setUnderLineText(tv, "some");

Prend également en charge les enfants TextView comme 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);
            }
        }
    }

vérifiez ma réponse ici pour rendre le texte de soulignement cliquable ou souligner plusieurs parties de TextView

Khemraj
la source
2

essayez ce code

en XML

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

dans du code

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

Bonne chance!

Andrew.J
la source
2
  1. Accédez au fichier de ressources strings.xml
  2. Ajoutez une chaîne dans le fichier de ressources avec une balise de soulignement HTML si nécessaire.

strings.xml exemple de soulignement HTML

  1. Appelez l'ID de ressource de chaîne dans votre code Java comme suit:
sampleTextView.setText(R.string.sample_string);
  1. La sortie doit avoir le mot "Stackoverflow" souligné.

De plus, le code suivant n'imprimera pas le soulignement:

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

Utilisez plutôt le code suivant pour conserver le format de texte enrichi:

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

"Vous pouvez utiliser getString (int) ou getText (int) pour récupérer une chaîne. GetText (int) conserve tout style de texte enrichi appliqué à la chaîne." Documentation Android.

Reportez-vous à la documentation: https://developer.android.com/guide/topics/resources/string-resource.html

J'espère que ça aide.

Fahmi Eshaq
la source
2

La réponse la plus votée est juste et la plus simple. Cependant, parfois, vous constaterez que cela ne fonctionne pas pour certaines polices, mais fonctionne pour d'autres (quel problème je viens de rencontrer en traitant le chinois).

La solution est de ne pas utiliser "WRAP_CONTENT" uniquement pour votre TextView, car il n'y a pas d'espace supplémentaire pour tracer la ligne. Vous pouvez définir une hauteur fixe pour votre TextView, ou utiliser android: paddingVertical avec WRAP_CONTENT.

Ray Lee
la source
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>

Notez le symbole d'échappement dans le fichier xml

lynn8570
la source
travaillé pour moi avec les symboles d'échappement, merci!
Badr au
1

Pour faire cela à Kotlin:

yourTextView.paint?.isUnderlineText = true

Re'em
la source
0

Il est assez tard pour répondre à cela, mais supposez que si quelqu'un veut obtenir le texte de manière dynamique, il peut utiliser cette simple ligne dans son code java qui fonctionne:

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

J'ai eu un problème où j'utilise une police personnalisée et le soulignement créé avec le fichier de ressources trick ( <u>Underlined text</u>) a fonctionné mais Android a réussi à transformer le soulignement en une sorte de creux.

J'ai utilisé cette réponse pour dessiner moi-même une bordure sous la vue de texte: https://stackoverflow.com/a/10732993/664449 . De toute évidence, cela ne fonctionne pas pour le texte souligné partiel ou le texte multiligne.

Rick Pastoor
la source