Définir la couleur de l'étendue TextView dans Android


206

Est-il possible de définir la couleur de la seule étendue de texte dans une TextView?

Je voudrais faire quelque chose de similaire à l'application Twitter, dans laquelle une partie du texte est bleue. Voir l'image ci-dessous:

texte alternatif
(source: twimg.com )

Réponses:


430

Une autre réponse serait très similaire, mais n'aurait pas besoin de définir le texte du TextViewdouble

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

mais comment puis-je changer la couleur de plusieurs mots dans tout le texte et non dans une seule plage?
mostafa hashim

1
@mostafahashim crée plusieurs plages en répétant la ligne 3 wordtoSpan.setSpan (new ForegroundColorSpan (Color.RED), 50, 80, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Ashraf Alshahawy

La solution Kotlin + Spannable String ressemblerait à ceci stackoverflow.com/questions/4032676/…
Dmitrii Leonov

82

Voici une petite fonction d'aide. Idéal lorsque vous avez plusieurs langues!

private void setColor(TextView view, String fulltext, String subtext, int color) {
    view.setText(fulltext, TextView.BufferType.SPANNABLE);
    Spannable str = (Spannable) view.getText();
    int i = fulltext.indexOf(subtext);
    str.setSpan(new ForegroundColorSpan(color), i, i + subtext.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}

38

Je trouve toujours des exemples visuels utiles lorsque j'essaie de comprendre un nouveau concept.

Couleur de l'arrière plan

entrez la description de l'image ici

SpannableString spannableString = new SpannableString("Hello World!");
BackgroundColorSpan backgroundSpan = new BackgroundColorSpan(Color.YELLOW);
spannableString.setSpan(backgroundSpan, 0, spannableString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);

Couleur de premier plan

entrez la description de l'image ici

SpannableString spannableString = new SpannableString("Hello World!");
ForegroundColorSpan foregroundSpan = new ForegroundColorSpan(Color.RED);
spannableString.setSpan(foregroundSpan, 0, spannableString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);

Combinaison

entrez la description de l'image ici

SpannableString spannableString = new SpannableString("Hello World!");
ForegroundColorSpan foregroundSpan = new ForegroundColorSpan(Color.RED);
BackgroundColorSpan backgroundSpan = new BackgroundColorSpan(Color.YELLOW);
spannableString.setSpan(foregroundSpan, 0, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(backgroundSpan, 3, spannableString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);

Une étude plus approfondie


30

Si vous voulez plus de contrôle, vous voudrez peut-être vérifier la TextPaintclasse. Voici comment l'utiliser:

final ClickableSpan clickableSpan = new ClickableSpan() {
    @Override
    public void onClick(final View textView) {
        //Your onClick code here
    }

    @Override
    public void updateDrawState(final TextPaint textPaint) {
        textPaint.setColor(yourContext.getResources().getColor(R.color.orange));
        textPaint.setUnderlineText(true);
    }
};

getColor (int id) est déconseillé sur Android 6.0 Marshmallow (API 23) stackoverflow.com/questions/31590714/…
Eka putra

Belle réponse avec Click Listener.
Muhaiminur Rahman

20

Définissez TextViewle texte de votre texte et définissez un ForegroundColorSpanpour votre texte.

TextView textView = (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);    
textView.setText(wordtoSpan);

Merci! Est-il possible de le faire sans affecter d'abord le texte au TextView?
hpique

Je ne m'explique pas bien. Permettez-moi de reformuler. Les 3 premières lignes sont-elles nécessaires? Vous ne pouvez pas créer directement l'objet extensible à partir de la chaîne?
hpique

Non, vous devez stocker le texte de votre TextView dans un Buffer Spannable pour changer la couleur de premier plan.
Jorgesys

Je veux faire la même chose avec la couleur plus je veux que tout soit en gras sauf la partie colorée, cette partie que je veux être en italique, comment faire?
Lukap

1
comment définir le clic dans la durée?
Rishabh Srivastava

14

Une autre façon qui pourrait être utilisée dans certaines situations est de définir la couleur du lien dans les propriétés de la vue qui prend le Spannable.

Si votre Spannable va être utilisé dans un TextView, par exemple, vous pouvez définir la couleur du lien dans le XML comme ceci:

<TextView
    android:id="@+id/myTextView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textColorLink="@color/your_color"
</TextView>

Vous pouvez également le définir dans le code avec:

TextView tv = (TextView) findViewById(R.id.myTextView);
tv.setLinkTextColor(your_color);

6

Il y a une usine pour créer le Spannable, et éviter le casting, comme ceci:

Spannable span = Spannable.Factory.getInstance().newSpannable("text");

1
Pourriez-vous clarifier comment utiliser SpannableFactory? À quoi devrait ressembler le «texte»?
Piotr

après avoir créé le Spannable par le SpannableFactory, alors comment l'utiliser?
MBH

6

Définissez la couleur sur le texte en passant la chaîne et la couleur :

private String getColoredSpanned(String text, String color) {
  String input = "<font color=" + color + ">" + text + "</font>";
  return input;
}

Définissez le texte sur TextView / Button / EditText, etc. en appelant le code ci-dessous:

Affichage:

TextView txtView = (TextView)findViewById(R.id.txtView);

Obtenez une chaîne colorée:

String name = getColoredSpanned("Hiren", "#800000");

Définissez le texte sur TextView:

txtView.setText(Html.fromHtml(name));

Terminé


5
String text = "I don't like Hasina.";
textView.setText(spannableString(text, 8, 14));

private SpannableString spannableString(String text, int start, int end) {
    SpannableString spannableString = new SpannableString(text);
    ColorStateList redColor = new ColorStateList(new int[][]{new int[]{}}, new int[]{0xffa10901});
    TextAppearanceSpan highlightSpan = new TextAppearanceSpan(null, Typeface.BOLD, -1, redColor, null);

    spannableString.setSpan(highlightSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannableString.setSpan(new BackgroundColorSpan(0xFFFCFF48), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannableString.setSpan(new RelativeSizeSpan(1.5f), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    return spannableString;
}

Production:

entrez la description de l'image ici


vous n'aimez pas Hasina 🤣
Abu Nayem

4

Juste pour ajouter à la réponse acceptée, car toutes les réponses semblent parler android.graphics.Coloruniquement: et si la couleur que je veux est définie dans res/values/colors.xml?

Par exemple, considérez les couleurs Material Design définies dans colors.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="md_blue_500">#2196F3</color>
</resources>

( android_material_design_colours.xmlest votre meilleur ami)

Ensuite, utilisez ContextCompat.getColor(getContext(), R.color.md_blue_500)où vous souhaitez utiliser Color.BLUE, de sorte que:

wordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE), 15, 30, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

devient:

wordtoSpan.setSpan(new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.md_blue_500)), 15, 30, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

Où j'ai trouvé ça:


3

Voici une fonction d'extension Kotlin que j'ai pour cela

    fun TextView.setColouredSpan(word: String, color: Int) {
        val spannableString = SpannableString(text)
        val start = text.indexOf(word)
        val end = text.indexOf(word) + word.length
        try {
            spannableString.setSpan(ForegroundColorSpan(color), start, end,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
            text = spannableString
        } catch (e: IndexOutOfBoundsException) {
         println("'$word' was not not found in TextView text")
    }
}

Utilisez-le après avoir défini votre texte sur TextView comme ceci

private val blueberry by lazy { getColor(R.color.blueberry) }

textViewTip.setColouredSpan("Warning", blueberry)

1
  1. créer une vue de texte dans votre mise en page
  2. collez ce code dans ur MainActivity

    TextView textview=(TextView)findViewById(R.id.textviewid);
    Spannable spannable=new SpannableString("Hello my name is sunil");
    spannable.setSpan(new ForegroundColorSpan(Color.BLUE), 0, 5, 
    Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
    textview.setText(spannable);
    //Note:- the 0,5 is the size of colour which u want to give the strring
    //0,5 means it give colour to starting from h and ending with space i.e.(hello), if you want to change size and colour u can easily

1

Ci-dessous fonctionne parfaitement pour moi

    tvPrivacyPolicy = (TextView) findViewById(R.id.tvPrivacyPolicy);
    String originalText = (String)tvPrivacyPolicy.getText();
    int startPosition = 15;
    int endPosition = 31;

    SpannableString spannableStr = new SpannableString(originalText);
    UnderlineSpan underlineSpan = new UnderlineSpan();
    spannableStr.setSpan(underlineSpan, startPosition, endPosition, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

    ForegroundColorSpan backgroundColorSpan = new ForegroundColorSpan(Color.BLUE);
    spannableStr.setSpan(backgroundColorSpan, startPosition, endPosition, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

    StyleSpan styleSpanItalic  = new StyleSpan(Typeface.BOLD);

    spannableStr.setSpan(styleSpanItalic, startPosition, endPosition, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

    tvPrivacyPolicy.setText(spannableStr);

Sortie pour le code ci-dessus

entrez la description de l'image ici


1

Certaines réponses ici ne sont pas à jour. Parce que, vous allez (dans la plupart des cas) ajouter une action de clic personnalisée sur votre lien .

En outre, comme indiqué dans l'aide à la documentation, la couleur de votre lien de chaîne étendue aura une couleur par défaut. "La couleur de lien par défaut est la couleur d'accentuation du thème ou android: textColorLink si cet attribut est défini dans le thème".

Voici la façon de le faire en toute sécurité.

 private class CustomClickableSpan extends ClickableSpan {

    private int color = -1;

    public CustomClickableSpan(){
        super();
        if(getContext() != null) {
            color = ContextCompat.getColor(getContext(), R.color.colorPrimaryDark);
        }
    }

    @Override
    public void updateDrawState(@NonNull TextPaint ds) {
        ds.setColor(color != -1 ? color : ds.linkColor);
        ds.setUnderlineText(true);
    }

    @Override
    public void onClick(@NonNull View widget) {
    }
}

Ensuite, pour l'utiliser.

   String text = "my text with action";
    hideText= new SpannableString(text);
    hideText.setSpan(new CustomClickableSpan(){

        @Override
        public void onClick(@NonNull View widget) {
            // your action here !
        }

    }, 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    yourtextview.setText(hideText);
    // don't forget this ! or this will not work !
    yourtextview.setMovementMethod(LinkMovementMethod.getInstance());

J'espère que cela vous aidera fortement!


1

À partir des documents du développeur, pour modifier la couleur et la taille d'un spannable:

1- créer une classe:

    class RelativeSizeColorSpan(size: Float,@ColorInt private val color: Int): RelativeSizeSpan(size) {

    override fun updateDrawState(textPaint: TextPaint?) {
        super.updateDrawState(textPaint)
        textPaint?.color = color
    } 
}

2 Créez votre spannable en utilisant cette classe:

    val spannable = SpannableStringBuilder(titleNames)
spannable.setSpan(
    RelativeSizeColorSpan(1.5f, Color.CYAN), // Increase size by 50%
    titleNames.length - microbe.name.length, // start
    titleNames.length, // end
    Spannable.SPAN_EXCLUSIVE_INCLUSIVE
)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.