web-dev-qa-db-fra.com

SpannableStringBuilder pour créer une chaîne avec plusieurs polices / tailles de texte, etc. Exemple?

J'ai besoin de créer une chaîne placée dans un TextView qui affichera une chaîne comme ceci:

La première partie n'est pas en gras [~ # ~] gras [~ # ~] le reste n'est pas gras

Donc, je veux savoir comment je pourrais utiliser SpannableStringBuilder pour faire cela?

Je pourrais utiliser trois TextEdit pour accomplir cela, mais j'aimerais utiliser la meilleure solution.

67
Code Droid
First Part Not Bold   BOLD  rest not bold

Vous pouvez le faire comme suggéré par @Rajesh ou par ceci.

String normalBefore= "First Part Not Bold ";
String normalBOLD=  "BOLD ";
String normalAfter= "rest not bold";
String finalString= normalBefore+normalBOLD+normalAfter;
Spannable sb = new SpannableString( finalString );
sb.setSpan(new StyleSpan(Android.graphics.Typeface.BOLD), finalString.indexOf(normalBOLD)+ normalBOLD.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); //bold
sb.setSpan(new AbsoluteSizeSpan(intSize), finalString.indexOf(normalBOLD)+ normalBOLD.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);//resize size

montrer ceci dans TextView

textview.setText(sb,  TextView.BufferType.SPANNABLE);
72
Azhar Shaikh

La réponse acceptée est correcte (et je l'ai votée vers le haut), mais le programme SpannableStringBuilder n'a pas été utilisé comme demandé par l'émetteur. Comme j'ai eu un cas où le constructeur avait le plus de sens, voici le code pour cela (avec une utilisation supplémentaire de changer également la couleur du texte si cela peut aider les autres). Notez que vous pouvez également fournir la chaîne initiale au constructeur SpannableStringBuilder, mais je l’ai définie ici pour utiliser "append" afin de préciser que vous pouvez ajouter beaucoup avant le texte "gras" souhaité, puis enregistrer le début comme indiqué. Je soupçonne que c'est aussi un code plus rapide que la réponse acceptée.

SpannableStringBuilder longDescription = new SpannableStringBuilder();
longDescription.append("First Part Not Bold ");
int start = longDescription.length();
longDescription.append("BOLD");
longDescription.setSpan(new ForegroundColorSpan(0xFFCC5500), start, longDescription.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
longDescription.setSpan(new StyleSpan(Android.graphics.Typeface.BOLD), start, longDescription.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
longDescription.append(" rest not bold");
70
Josh

De API 21 SpannableStringBuilder inclut une méthode simple pour le faire. Voici un exemple de solution:

SpannableStringBuilder builder= new SpannableStringBuilder();
StyleSpan boldSpan = new StyleSpan(Android.graphics.Typeface.BOLD);
builder.append("First Part Not Bold ")
              .append("BOLD ", boldSpan, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
              .append("rest not bold");

Comme il est fort probable que vous ne supportiez pas API 21, vous pouvez dupliquer le code à partir de cette méthode:

public SpannableStringBuilder append(CharSequence text, Object what, int flags) {
        int start = length();
        append(text);
        setSpan(what, start, length(), flags);
        return this;
}
36
Gober

Si vous utilisez Kotlin, vous pouvez effectuer les opérations suivantes à l'aide de la bibliothèque Android-ktx

val s = SpannableStringBuilder()
        .append("First Part Not Bold ")
        .bold { append("BOLD") } 
        .append("Rest not bold")

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 s = SpannableStringBuilder()
            .color(green, { append("Green text ") })
            .append("Normal text ")
            .scale(0.5, { append("Text at half size " })
            .backgroundColor(green, { append("Background green") })

green est une couleur RVB résolue.

Il est même possible d'imbriquer des étendues pour vous retrouver avec 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'
}
15
David Rawson

Utilisez du code HTML dans TextView en utilisant la classe Html :

Spanned styledText = Html.fromHtml("First Part Not Bold <b>BOLD</b> rest not bold");
textView.setText(styledText);
6
Rajesh

Ce code doit définir en gras tout ce qui se trouve dans la balise HTML en gras. Et cela supprime également la balise pour que seul le contenu à l'intérieur soit affiché.

        SpannableStringBuilder sb = new SpannableStringBuilder("this is <b>bold</b> and this is <b>bold too</b>  and this is <b>bold too, again</b>.");

        Pattern p = Pattern.compile("<b>.*?</b>", Pattern.CASE_INSENSITIVE);            
        boolean stop = false;
        while (!stop)
        {
            Matcher m = p.matcher(sb.toString());
            if (m.find()) {
                sb.setSpan(new StyleSpan(Android.graphics.Typeface.BOLD), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
                sb.delete(m.end()-4, m.end());
                sb.delete(m.start(), m.start() + 3);
            }
            else
                stop = true;
        }

Ce code peut également être adapté à d'autres balises de style html, telles que Superscript (balise sup), etc.

        SpannableStringBuilder sb = new SpannableStringBuilder("text has <sup>superscript</sup> tag");

        Pattern p = Pattern.compile("<sup>.*?</sup>", Pattern.CASE_INSENSITIVE);            
        boolean stop = false;
        while (!stop)
        {
            Matcher m = p.matcher(sb.toString());
            if (m.find()) {
                sb.setSpan(new SuperscriptSpan(), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
                sb.delete(m.end()-6, m.end());
                sb.delete(m.start(), m.start() + 5);
            }
            else
                stop = true;
        }

Pour définir la couleur, utilisez simplement ForegroundColorSpan avec setSpan.

sb.setSpan(new ForegroundColorSpan(Color.rgb(255, 0, 0)), m.start(), m.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);

J'espère que ça aide.

4
live-love

Donc, je sais que cela a été résolu, et même comme demandé avec SpannableStringBuilder, mais si vous vouliez construire une chaîne de manière plus dynamique, je me suis dit que je la mettrais en place.

// Stuff needed
TextView DataTextView = (TextView)rootView.findViewById(R.id.DataView);
String Fields[] = {...database column names as strings... "x","y"};

String DataString = new String();   

int start,stop;     // Start and Stop of formatting

// Final Result
SpannableStringBuilder coloredString = new SpannableStringBuilder(); 

SpannableString temp;       // Small segment of colored string
for (int i =0; i < Fields.length; i++)
{
    if (database_result.containsKey(Fields[i]))  // Be sure a field exists in the ContentValues
    {
            DataString = Fields[i]+": ";
        start = DataString.length();
        DataString = DataString+ +database_result.getAsInteger(Fields[i])+" ";
        stop= DataString.length();
        temp = new SpannableString(DataString);
        temp.setSpan(new ForegroundColorSpan(Color.WHITE),start, stop, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        coloredString.append(temp);
    }   
}
DataTextView.setText(coloredString);

database_result est un type ContentValues ​​que j'ai construit à partir du type Cursor renvoyé de la requête SQL. Le seul problème que j'ai eu avec ceci était au début c'était seulement ColorSpaning le premier segment. Il est évident que vous devez déclarer un nouveau ForegroundColorSpan chaque fois que vous souhaitez utiliser un (ou un autre type d'étendue) dans une boucle.

3
Zeppie

Nous pouvons également utiliser SpannableStringBuilder avec TextAppearanceSpan pour accomplir cela. Suivez les étapes ci-dessous pour mettre en œuvre comme ça.

  1. Créer un style dans styles.xml.
<style name="BoldStyle">
   <!-- Can add other styling attributes -->
   <item name="Android:textStyle">bold</item>
   ......
</style>
  1. Utilisez le code ci-dessous.
 Constructeur SpannableStringBuilder = new SpannableStringBuilder ("La première partie n'est pas en gras, le gras ne se met pas en gras"); 
 Builder.setSpan (nouveau, TextAppearanceSpan (this, R.style.BoldStyle), 20, 24, 0) ; 
 ((TextView) findViewById (R.id.tv7)). SetText (constructeur); 

C'est ça. J'espère que ça va aider quelqu'un.

2
Mahendran Sakkarai

Pourquoi voudriez-vous utiliser SpannableStringBuilder quand vous pouvez utiliser SpannableBuilder ?? ( https://Gist.github.com/qtyq/90f9b4894069a8b3676c) )

SpannableString ss = SpannableBuilder.init("First Part Not Bold BOLD rest not bold")
                                     .makeBold("BOLD")
                                     .create()
1
qtyq