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 )

hpique
la source

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);
DanO
la source
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);
}
mach
la source
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

Suragch
la source
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);
    }
};
Tiago
la source
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);
Jorgesys
la source
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);
Dave
la source
6

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

Spannable span = Spannable.Factory.getInstance().newSpannable("text");
Thomas Emil Hansen
la source
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é

Hiren Patel
la source
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

Ahamadullah Saikat
la source
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:

Antonio Vinicius Menezes Medei
la source
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)
Ivan Wooll
la source
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
Sunil
la source
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

OmiK
la source
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!

Zhar
la source
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
)
Badr
la source