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?
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?
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);
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!
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);
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), etSTRIKE
(strikethrough). Ainsi, par exemple, dansres/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.
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.
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
- expliquer la signification des indicateurs de portée comme SPAN_EXCLUSIVE_EXCLUSIVE
- Android Spanned, SpannedString, Spannable, SpannableString et CharSequence
- types de travées
cet exemple a été inspiré à l'origine de ici .
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;
}
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> "));
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
]]>"
/>
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
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
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)
}
}
}
}
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é.
Il pourrait être aussi simple que de tirer parti de la longueur de la Chaîne() la méthode:
-
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.
-
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...
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!
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)
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>
]]>