Je cherche à changer le texte d'une vue TextView via la méthode .setText ("") tout en colorant une partie du texte (ou en le mettant en gras, en italique, en transparence, etc.) et non le reste. Par exemple:
title.setText("Your big island <b>ADVENTURE!</b>";
Je sais que le code ci-dessus est incorrect, mais cela aide à illustrer ce que j'aimerais réaliser. Comment je ferais ça?
Utilisez span .
Exemple:
final SpannableStringBuilder sb = new SpannableStringBuilder("your text here");
// Span to set text color to some RGB value
final ForegroundColorSpan fcs = new ForegroundColorSpan(Color.rgb(158, 158, 158));
// Span to make text bold
final StyleSpan bss = new StyleSpan(Android.graphics.Typeface.BOLD);
// Set the text color for first 4 characters
sb.setSpan(fcs, 0, 4, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
// make them also bold
sb.setSpan(bss, 0, 4, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
yourTextView.setText(sb);
title.setText(Html.fromHtml("Your big island <b>ADVENTURE!</b>"));
J'espère que cela vous aide (cela fonctionne avec plusieurs langues).
<string name="test_string" ><![CDATA[<font color="%1$s"><b>Test/b></font>]]> String</string>
Et sur votre code Java, vous pouvez faire:
int color = context.getResources().getColor(Android.R.color.holo_blue_light);
String string = context.getString(R.string.test_string, color);
textView.setText(Html.fromHtml(string));
De cette façon, seule la partie "Test" sera colorée (et en gras).
Voici un exemple qui cherchera toutes les occurrences d'un mot (insensible à la casse) et les colorera en rouge:
String notes = "aaa AAA xAaax abc aaA xxx";
SpannableStringBuilder sb = new SpannableStringBuilder(notes);
Pattern p = Pattern.compile("aaa", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(notes);
while (m.find()){
//String Word = m.group();
//String Word1 = notes.substring(m.start(), m.end());
sb.setSpan(new ForegroundColorSpan(Color.rgb(255, 0, 0)), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
}
editText.setText(sb);
Vous pouvez utiliser un Spannable
pour donner certains aspects à certaines parties d'un texte. Je peux chercher un exemple si vous voulez.
Ah, à partir d’ici stackoverflow .
TextView TV = (TextView)findViewById(R.id.mytextview01);
Spannable WordtoSpan = new SpannableString("I know just how to whisper, And I know just how to cry,I know just where to find the answers");
WordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE), 15, 30, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
TV.setText(WordtoSpan);
Si vous voulez utiliser HTML, vous devez utiliser TextView.setText(Html.fromHtml(String htmlString))
Si vous voulez faire cela souvent/plusieurs fois, vous pouvez jeter un oeil à une classe ( SpannableBuilder ) que j'ai écrit, car Html.fromHtml()
n'est pas très efficace (il utilise un gros xml analyse des machines à l'intérieur). Il est décrit dans ce blogging .
Si vous utilisez Kotlin, vous pouvez effectuer les opérations suivantes à l'aide de la bibliothèque Android-ktx
val title = SpannableStringBuilder()
.append("Your big island ")
.bold { append("ADVENTURE") }
title.text = s
bold
est une fonction d'extension sur SpannableStringBuilder
. Vous pouvez voir la documentation ici pour une liste des opérations que vous pouvez utiliser.
Un autre exemple:
val ssb = SpannableStringBuilder()
.color(green, { append("Green text ") })
.append("Normal text ")
.scale(0.5, { append("Text at half size " })
.backgroundColor(green, { append("Background green") })
Où green
est une couleur RVB résolue.
Il est même possible d'imbriquer des étendues pour aboutir à quelque chose comme un DSL intégré:
bold { underline { italic { append("Bold and underlined") } } }
Vous aurez besoin des éléments suivants dans le niveau de module de votre application build.gradle
pour que cela fonctionne:
repositories {
google()
}
dependencies {
implementation 'androidx.core:core-ktx:0.3'
}
tilisez ce code pour vous aider
TextView txtTest = (TextView) findViewById(R.id.txtTest);
txtTest.setText(Html.fromHtml("This is <font color="#ff4343">Red</font> Color!"));
String str1 = "If I forget my promise to ";
String penalty = "Eat breakfast every morning,";
String str2 = " then I ";
String promise = "lose my favorite toy";
String strb = "<u><b><font color='#081137'>"+ penalty +",</font></b></u>";
String strc = "<u><b><font color='#081137'>"+ promise + "</font></b></u>";
String strd = str1 +strb+ str2 + strc;
tv_notification.setText(Html.fromHtml(strd));
ou utilisez ce code:
SpannableStringBuilder builder = new SpannableStringBuilder();
SpannableString text1 = new SpannableString(str1);
text1.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.silver)), 0, str1.length() - 1, 0);
builder.append(text1);
SpannableString text2 = new SpannableString(penalty);
text2.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.midnight)), 0, penalty.length(), 0);
text2.setSpan(new UnderlineSpan(), 0, penalty.length(), 0);
builder.append(text2);
SpannableString text3 = new SpannableString(str2);
text3.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.silver)),0, str2.length(), 0);
builder.append(text3);
SpannableString text4 = new SpannableString(promise);
text4.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.midnight)), 0, promise.length(), 0);
text4.setSpan(new UnderlineSpan(),0, promise.length(), 0);
builder.append(text4);
tv_notification.setText(builder);
Vous pouvez concaténer deux ou plusieurs plages. De cette façon, il est plus facile de colorer un texte dynamique en utilisant la valeur de la longueur.
SpannableStringBuilder span1 = new SpannableStringBuilder("Android");
ForegroundColorSpan color1=new ForegroundColorSpan(getResources().getColor(R.color.colorPrimary));
span1.setSpan(color1, 0, span1.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
SpannableStringBuilder span2 = new SpannableStringBuilder("Love");
ForegroundColorSpan color2=new ForegroundColorSpan(getResources().getColor(R.color.colorSecondary));
span2.setSpan(color2, 0, span2.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
Spanned concatenated=(Spanned) TextUtils.concat(span1," => ",span2);
SpannableStringBuilder result = new SpannableStringBuilder(concatenated);
TextView tv = (TextView) rootView.findViewById(R.id.my_texview);
tv.setText(result, TextView.BufferType.SPANNABLE);
J'aime utiliser SpannableStringBuilder
en ajoutant les différentes plages une par une, plutôt que d'appeler setSpan en calculant la longueur des chaînes
comme: (code Kotlin)
val amountSpannableString = SpannableString("₹$amount").apply {
// text color
setSpan(ForegroundColorSpan("#FD0025".parseColor()), 0, length, 0)
// text size
setSpan(AbsoluteSizeSpan(AMOUNT_SIZE_IN_SP.spToPx(context)), 0, length, 0)
// font medium
setSpan(TypefaceSpan(context.getString(R.string.font_roboto_medium)), 0, length, 0)
}
val spannable: Spannable = SpannableStringBuilder().apply {
// append the different spans one by one
// rather than calling setSpan by calculating the string lengths
append(TEXT_BEFORE_AMOUNT)
append(amountSpannableString)
append(TEXT_AFTER_AMOUNT)
}
public static void setColorForPath(Spannable spannable, String[] paths, int color) {
for (int i = 0; i < paths.length; i++) {
int indexOfPath = spannable.toString().indexOf(paths[i]);
if (indexOfPath == -1) {
continue;
}
spannable.setSpan(new ForegroundColorSpan(color), indexOfPath,
indexOfPath + paths[i].length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
En utilisant
Spannable spannable = new SpannableString("Your big island ADVENTURE");
Utils.setColorForPath(spannable, new String[] { "big", "ADVENTURE" }, Color.BLUE);
textView.setText(spannable);