3

Ok, so I gather that this should be a fairly straightforward process.

I've read the following questions:

The advice seems to be pretty similar across all of these questions and answers. I'm trying to avoid the HTML techniques and use SpannableString and SpannableStringBuilder instead. Ultimately, I'd like to be able to use multiple different typefaces in a single TextView, but for now, I'd just like to figure out how to get multiple colors working.

I'm trying to implement those techniques in this way:

// Get a typeface for my custom font
String regularFontPath          = "fonts/Abel-Regular.ttf";
Typeface regularTf              = Typeface.createFromAsset(getActivity().getAssets(), regularFontPath);

// Set the label's typeface (this part is working)
mItemCodesLabel.setTypeface(regularTf);

// Create a spannable builder to build up my
// TextView's content from data
SpannableStringBuilder builder  = new SpannableStringBuilder();

// These colors are defined and working well in other parts of my app
ForegroundColorSpan ltGraySpan  = new ForegroundColorSpan(R.color.light_gray);
ForegroundColorSpan dkGraySpan  = new ForegroundColorSpan(R.color.dark_gray);

// mCodesList has good data and the actual data output from this
// loop is correct. Just the styling is wrong
for (int i = 0; i < mCodesList.size(); i = i + 1) {
    ParseObject code            = mCodesList.get(i);
    String value                = code.getString("value") + " | ";
    if (i > 0) {
        // I want new codes to be on a new line (this works)
        value                   = "\n" + value;
    }
    SpannableString valueSpan   = new SpannableString(value);
    valueSpan.setSpan(ltGraySpan, 0, value.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    builder.append(valueSpan);

    String loc                  = code.getString("location");
    SpannableString locSpan     = new SpannableString(loc);
    locSpan.setSpan(dkGraySpan, 0, loc.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    builder.append(locSpan);
}
mItemCodesLabel.setText(builder);

The net result is that the TextView contains the correct text contents. The TextView is the correct typeface. But the entire contents of the TextView are my @color/light_gray color. I'm not sure why, because in the XML layout file, I had specified my @color/dark_gray color (which I expect to be overridden by setting the text with a Spannable). Even if I change both ForegroundColorSpan objects to use R.color.dark_gray, the TextView still comes out light gray. I don't see anywhere else in my code where I'm setting the color of the text, so I'm really at a loss.

I'm running this on an LG Optimus G Pro, which is running 4.4.2. I have another TextView where I need to get multiple colors and font working and even underline some parts of the text, so this is a pretty big deal for me. Where am I going wrong?

Community
  • 1
  • 1
mbm29414
  • 11,558
  • 6
  • 56
  • 87

2 Answers2

3

use getResource().getColor(R.color.light_gray) to retrieve the color you are passing to the ForegroundColorSpan. I doubt it is retrieving it internally for you. You probably need to instantiate a new ForegroundColorSpan at every iteration. It is not possible to reuse it

Blackbelt
  • 156,034
  • 29
  • 297
  • 305
  • 1
    If that really is the answer, I'm going to beat my head against the wall! ;-) I'll give that a shot and get back to you. Thanks for answering. Why does it let me use that syntax if that syntax won't actually work? – mbm29414 May 07 '15 at 13:31
  • the method takes an int and both the colour and the id of the colour are int – Blackbelt May 07 '15 at 13:32
  • Well, at least this was a big enough frustration that I will have learned this lesson once and for all! Thanks again for your help! – mbm29414 May 07 '15 at 13:33
  • After checking this out, it works beautifully! Thanks! I also learned (the hard way) that you have to create a new *Span object for each section you wish to customize. If you try to reuse *Span objects, it would appear that only the last application "sticks". Gahh! – mbm29414 May 07 '15 at 21:50
  • I am glad it worked out. Look at the bright side, next time you'll *probably* not do the same mistake – Blackbelt May 08 '15 at 07:05
2

You may Use SpannableStringBuilder because it implements from spannable and CharSequence, also you may do anything with following

TextView txtTest = (TextView) findViewById(R.id.txt);
String text = "This is an example";    
final SpannableStringBuilder str = new SpannableStringBuilder(text);
str.setSpan(new TypefaceSpan("monospace"), 0, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str.setSpan(new TypefaceSpan("serif"), 9, 12, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.white)), 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.grey)), 6, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
txtTest.setText(str);

I have add colors.xml in values

<color name="black">#000000</color>
<color name="grey">#DCDCDC</color>
<color name="white">#FFFFFF</color>
Abdul Rahman Majeed
  • 1,125
  • 2
  • 10
  • 22