Est-il possible d'avoir plusieurs styles dans un TextView?

est-il possible de définir plusieurs styles pour différents morceaux de texte à L'intérieur D'un TextView?

par exemple, je règle le texte comme suit:

tv.setText(line1 + "n" + line2 + "n" + word1 + "t" + word2 + "t" + word3);

Est-il possible d'avoir un style différent pour chaque élément de texte? Par exemple, ligne 1 gras, italique, etc.

le guide du développeur tâches communes et comment les faire dans Android comprend sélectionner, Mettre en évidence, ou le style Parties de texte :

// Get our EditText object.
EditText vw = (EditText)findViewById(R.id.text);

// Set the EditText's text.
vw.setText("Italic, highlighted, bold.");

// If this were just a TextView, we could do:
// vw.setText("Italic, highlighted, bold.", TextView.BufferType.SPANNABLE);
// to force it to use Spannable storage so styles can be attached.
// Or we could specify that in the XML.

// Get the EditText's internal text storage
Spannable str = vw.getText();

// Create our span sections, and assign a format to each.
str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str.setSpan(new BackgroundColorSpan(0xFFFFFF00), 8, 19, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 21, str.length() - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

mais qui utilise des numéros de position explicites à l'intérieur du texte. Est-il une manière plus propre de faire cela?

505
demandé sur blahdiblah 2009-10-07 05:33:34

17 réponses

au cas où, quelqu'un se demande comment faire, voici une façon: (merci à Mark encore!)

mBox = new TextView(context);
mBox.setText(Html.fromHtml("<b>" + title + "</b>" +  "<br />" + 
            "<small>" + description + "</small>" + "<br />" + 
            "<small>" + DateAdded + "</small>"));

pour une liste non officielle des balises supportées par cette méthode, reportez-vous à ce lien ou cette question: quelles balises HTML sont supportées par Android TextView?

678
répondu Legend 2017-05-23 11:47:30

essayez Html.fromHtml() , et marquez votre texte avec des balises HTML en gras et en italique E. g:

Spanned text = Html.fromHtml("This mixes <b>bold</b> and <i>italic</i> stuff");
textView.setText(text);
207
répondu CommonsWare 2015-01-31 21:30:15

légèrement hors sujet, mais j'ai trouvé cela trop utile pour ne pas être mentionné ici.

Que faire si nous aimerions lire le texte Html de la chaîne de caractères .la ressource xml facilite la localisation. CDATA rendre cela possible:

<string name="my_text">
  <![CDATA[
    <b>Autor:</b> Mr Nice Guy<br/>
    <b>Contact:</b> myemail@grail.com<br/>
    <i>Copyright © 2011-2012 Intergalactic Spacebar Confederation </i>
  ]]>
</string> 

de notre code Java, nous pouvons maintenant l'utiliser comme ceci:

TextView tv = (TextView) findViewById(R.id.myTextView);
tv.setText(Html.fromHtml(getString(R.string.my_text))); 

je ne m'attendais pas à ce travail. Mais il l'a fait.

J'espère que c'est utile pour certains d'entre vous!

177
répondu Ben 2011-11-03 11:20:44

si vous n'avez pas envie d'utiliser html, vous pouvez créer un style.xml et l'utiliser comme ceci:

TextView tv = (TextView) findViewById(R.id.textview);
SpannableString text = new SpannableString(myString);

text.setSpan(new TextAppearanceSpan(getContext(), R.style.myStyle), 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
text.setSpan(new TextAppearanceSpan(getContext(), R.style.myNextStyle), 6, 10, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

tv.setText(text, TextView.BufferType.SPANNABLE);
106
répondu Kent Andersen 2017-11-29 12:46:49

la liste des tags pris en charge est:

si vous utilisez une ressource string, vous pouvez ajouter un style simple, comme bold ou italic en utilisant la notation HTML. Les étiquettes actuellement prises en charge sont: B (gras), I (italique), U (souligné), TT (monospace), BIG , SMALL , SUP (superscript), SUB (subscript), et STRIKE (strikethrough). Ainsi, par exemple, dans res/values/strings.xml , vous pouvez déclarez ceci:

<resource>
    <string id="@+id/styled_welcome_message">We are <b><i>so</i></b> glad to see you.</string>
</resources>

(de http://developer.android.com/guide/faq/commontasks.html#selectingtext - lien D'Archive Web, <resource> la typographie est en original!)

Il montre aussi que Html.fromHtml n'est pas vraiment nécessaire dans les cas simples.

38
répondu Jon 2017-12-08 18:29:19

il est plus léger d'utiliser un SpannableString au lieu d'un balisage html. Il m'aide à voir des exemples visuels donc voici une réponse supplémentaire.

enter image description here

c'est un simple TextView .

// set the text
SpannableString s1 = new SpannableString("bold\n");
SpannableString s2 = new SpannableString("italic\n");
SpannableString s3 = new SpannableString("foreground color\n");
SpannableString s4 = new SpannableString("background color\n");
SpannableString s5 = new SpannableString("underline\n");
SpannableString s6 = new SpannableString("strikethrough\n");
SpannableString s7 = new SpannableString("bigger\n");
SpannableString s8 = new SpannableString("smaller\n");
SpannableString s9 = new SpannableString("font\n");
SpannableString s10 = new SpannableString("URL span\n");
SpannableString s11 = new SpannableString("clickable span\n");
SpannableString s12 = new SpannableString("overlapping spans\n");

// set the style
int flag = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
s1.setSpan(new StyleSpan(Typeface.BOLD), 0, s1.length(), flag);
s2.setSpan(new StyleSpan(Typeface.ITALIC), 0, s2.length(), flag);
s3.setSpan(new ForegroundColorSpan(Color.RED), 0, s3.length(), flag);
s4.setSpan(new BackgroundColorSpan(Color.YELLOW), 0, s4.length(), flag);
s5.setSpan(new UnderlineSpan(), 0, s5.length(), flag);
s6.setSpan(new StrikethroughSpan(), 0, s6.length(), flag);
s7.setSpan(new RelativeSizeSpan(2), 0, s7.length(), flag);
s8.setSpan(new RelativeSizeSpan(0.5f), 0, s8.length(), flag);
s9.setSpan(new TypefaceSpan("monospace"), 0, s9.length(), flag);
s10.setSpan(new URLSpan("https://developer.android.com"), 0, s10.length(), flag);
s11.setSpan(new ClickableSpan() {
    @Override
    public void onClick(View widget) {
        Toast.makeText(getApplicationContext(), "Span clicked", Toast.LENGTH_SHORT).show();
    }
}, 0, s11.length(), flag);
s12.setSpan(new ForegroundColorSpan(Color.RED), 0, 11, flag);
s12.setSpan(new BackgroundColorSpan(Color.YELLOW), 4, s12.length(), flag);
s12.setSpan(new UnderlineSpan(), 4, 11, flag);

// build the string
SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append(s1);
builder.append(s2);
builder.append(s3);
builder.append(s4);
builder.append(s5);
builder.append(s6);
builder.append(s7);
builder.append(s8);
builder.append(s9);
builder.append(s10);
builder.append(s11);
builder.append(s12);

// set the text view with the styled text
textView.setText(builder);
// enables clicking on spans for clickable span and url span
textView.setMovementMethod(LinkMovementMethod.getInstance());

Complément D'Étude

cet exemple a été inspiré à l'origine de ici .

36
répondu Suragch 2017-05-23 12:18:30

je rencontrais le même problème. Je pourrais utiliser fromHtml, mais je suis android maintenant, pas web, donc j'ai décidé de l'essayer. Je dois localiser ce bien que donc je lui ai donné un coup en utilisant le concept de remplacement de corde. J'ai placé le style sur le TextView pour être le style principal, puis juste formater les autres poires.

j'espère que cela aidera d'autres qui cherchent à faire la même chose - Je ne sais pas pourquoi ce n'est pas plus facile dans le cadre.

mes cordes ressemblent à ceci:


<string name="my_text">{0} You will need a {1} to complete this assembly</string>
<string name="text_sub0">1:</string>
<string name="text_sub1">screwdriver, hammer, and measuring tape</string>

Voici les styles:


<style name="MainStyle">
    <item name="android:textSize">@dimen/regular_text</item>
    <item name="android:textColor">@color/regular_text</item>
</style>
<style name="style0">
    <item name="android:textSize">@dimen/paragraph_bullet</item>
    <item name="android:textColor">@color/standout_text</item>
    <item name="android:textStyle">bold</item>
</style>
<style name="style1">
    <item name="android:textColor">@color/standout_light_text</item>
    <item name="android:textStyle">italic</item>
</style>

Voici mon code qui appelle ma méthode formatStyles:


SpannableString formattedSpan = formatStyles(getString(R.string.my_text), getString(R.string.text_sub0), R.style.style0, getString(R.string.main_text_sub1), R.style.style1);
textView.setText(formattedSpan, TextView.BufferType.SPANNABLE);

Le format de la méthode:


private SpannableString formatStyles(String value, String sub0, int style0, String sub1, int style1)
{
    String tag0 = "{0}";
    int startLocation0 = value.indexOf(tag0);
    value = value.replace(tag0, sub0);

    String tag1 = "{1}";
    int startLocation1 = value.indexOf(tag1);
    if (sub1 != null && !sub1.equals(""))
    {
        value = value.replace(tag1, sub1);
    }

    SpannableString styledText = new SpannableString(value);
    styledText.setSpan(new TextAppearanceSpan(getActivity(), style0), startLocation0, startLocation0 + sub0.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    if (sub1 != null && !sub1.equals(""))
    {
        styledText.setSpan(new TextAppearanceSpan(getActivity(), style1), startLocation1, startLocation1 + sub1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }

    return styledText;
}
16
répondu farcrats 2013-01-07 23:22:09

maintenant l'élément <b> est déprécié. <strong> rend <b> , et <em> rend <i> .

tv.setText(Html.fromHtml("<strong>bold</strong> and <em>italic</em> "));

cela fonctionne très bien pour moi

12
répondu Sandy09 2016-12-05 16:30:46

si vous voulez pouvoir ajouter le texte de style en xml, vous pouvez créer une vue personnalisée étendant TextView et outrepasser setText ():

public class HTMLStyledTextView extends TextView
{
    public HTMLStyledTextView(Context context) {
        super(context);
    }

    public HTMLStyledTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public HTMLStyledTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void setText(CharSequence text, BufferType type)
    {
       super.setText(Html.fromHtml(text.toString()), type);
    }
}

ensuite, vous pouvez l'utiliser comme ceci (remplacer PACKAGE_NAME par votre nom de paquet):

<PACKAGE_NAME.HTMLStyledTextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="<![CDATA[
        <b>Bolded Text:</b> Non-Bolded Text
    ]]>"
/>
6
répondu bcorso 2014-08-20 00:07:03

voici un moyen facile de le faire en utilisant HTMLBuilder

    myTextView.setText(new HtmlBuilder().
                    open(HtmlBuilder.Type.BOLD).
                    append("Some bold text ").
                    close(HtmlBuilder.Type.BOLD).
                    open(HtmlBuilder.Type.ITALIC).
                    append("Some italic text").
                    close(HtmlBuilder.Type.ITALIC).
                    build()
    );

résultat:

Certains texte en gras Certains texte en italique

6
répondu Ilya Gazman 2015-09-03 07:27:14

comme indiqué, utiliser TextView.setText(Html.fromHtml(String))

et utilisez ces balises dans votre chaîne HTML formatée:

<a href="...">
<b>
<big>
<blockquote>
<br>
<cite>
<dfn>
<div align="...">
<em>
<font size="..." color="..." face="...">
<h1>
<h2>
<h3>
<h4>
<h5>
<h6>
<i>
<img src="...">
<p>
<small>
<strike>
<strong>
<sub>
<sup>
<tt>
<u>

http://commonsware.com/blog/Android/2010/05/26/html-tags-supported-by-textview.html

6
répondu Andrew Gallasch 2015-10-03 11:45:51

Moi Aussi

Que Diriez - vous d'utiliser un beau balisage avec Kotlin et Anko -

import org.jetbrains.anko.*
override fun onCreate(savedInstanceState: Bundle?) {
    title = "Created with Beautiful Markup"
    super.onCreate(savedInstanceState)

    verticalLayout {
        editText {
            hint = buildSpanned {
                append("Italic, ", Italic)
                append("highlighted", backgroundColor(0xFFFFFF00.toInt()))
                append(", Bold", Bold)
            }
        }
    }
}

Created with Beautiful Markup

1
répondu Himanshu 2017-11-14 08:00:58

en fait, à l'exception de L'objet Html, vous pouvez également utiliser les classes de type "Spannable", par exemple TextAppearanceSpan ou TypefaceSpan et SpannableString togather. La classe Html utilise également ces mécanismes. Mais avec les cours de typographie, vous avez plus de liberté.

0
répondu Clock ZHONG 2014-08-11 10:01:21

Il pourrait être aussi simple que de tirer parti de la longueur de la Chaîne() la méthode:

  1. divisez la chaîne de texte dans le fichier XML Strings en autant de sous-chaînes (une chaîne séparée du point de vue D'Android) autant que vous avez besoin de styles différents, il pourrait donc être comme: str1, str2, str3 (comme dans votre cas), qui, une fois réunis, sont la chaîne unique entière que vous utilisez.

  2. et ensuite simplement suivre la méthode "Span", tout comme vous l'avez présenté avec votre code - mais au lieu d'une chaîne simple, combiner tous les substrats les fusionnant en un seul, chacun avec un style personnalisé différent.

vous utilisez toujours les nombres, mais pas directement - ils ne sont plus sous forme codée (comme dans votre code) maintenant, mais ils sont substitués avec les méthodes de longueur combinée () (notez deux étoiles précédant et suffixant le str.longueur() à la place de l'absolu, le nombre de extuinguish le changement):

str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, **str.length()**, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

pour la première taille de chaîne, puis str.Longueur () + 1, str.length () + str2.longueur () pour la deuxième taille de chaîne, et ainsi de suite avec tous les substrats, au lieu de par ex. 0,7 ou 8,19 et ainsi de suite...

0
répondu forsberg 2016-08-11 09:30:58

utilisant une classe Spannable auxiliaire comme Android String Resources actions au bas de la page web. Vous pouvez aborder cela en créant CharSquences et en leur donnant un style.

mais dans l'exemple qu'ils nous donnent, est juste pour le texte en gras, italique, et même coloriser. J'avais besoin d'envelopper plusieurs styles dans un CharSequence afin de les mettre dans un TextView . Donc à cette classe (je l'ai appelée CharSequenceStyles ) j'ai juste ajouté cette fonction.

public static CharSequence applyGroup(LinkedList<CharSequence> content){
    SpannableStringBuilder text = new SpannableStringBuilder();
    for (CharSequence item : content) {
        text.append(item);
    }
    return text;
}

et dans la vue j'ai ajouté ceci.

            message.push(postMessageText);
            message.push(limitDebtAmount);
            message.push(pretMessageText);
            TextView.setText(CharSequenceStyles.applyGroup(message));

j'espère que cela vous aidera!

0
répondu MontDeska 2017-06-07 23:15:18

Spanny rendre SpannableString plus facile à utiliser.

Spanny spanny = new Spanny("Underline text", new UnderlineSpan())
                .append("\nRed text", new ForegroundColorSpan(Color.RED))
                .append("\nPlain text");
textView.setText(spanny)
0
répondu Desmond Lua 2017-08-17 15:53:22

Comme Jon dit , pour moi c'est la meilleure solution et vous n'avez pas besoin de définir n'importe quel texte au moment de l'exécution, utilisez uniquement cette classe personnalisée HtmlTextView

public class HtmlTextView extends TextView {

  public HtmlTextView(Context context) {
      super(context);
  }

  public HtmlTextView(Context context, AttributeSet attrs) {
      super(context, attrs);
  }

  public HtmlTextView(Context context, AttributeSet attrs, int defStyleAttr) 
  {
      super(context, attrs, defStyleAttr);
  }

  @TargetApi(21)
  public HtmlTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
      super(context, attrs, defStyleAttr, defStyleRes);
  }

  @Override
  public void setText(CharSequence s,BufferType b){
      super.setText(Html.fromHtml(s.toString()),b);
  }

}

et c'est tout, maintenant mettez-le seulement dans votre XML

<com.fitc.views.HtmlTextView
    android:id="@+id/html_TV"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/example_html" />

avec votre chaîne Html

<string name="example_html">
<![CDATA[
<b>Author:</b> Mr Donuthead<br/>
<b>Contact:</b> me@donut.com<br/>
<i>Donuts for life </i>
]]>

0
répondu AWolfsdorf 2017-10-18 12:46:25