Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ForegroundColorSpan is not applied to ReplacementSpan

I'm trying to utilize ReplacementSpans to format the input in a EditText Field (without modifying the content):

public class SpacerSpan extends ReplacementSpan {
    @Override
    public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
        return (int) paint.measureText(text.subSequence(start,end)+" ");
    }
    @Override
    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
        canvas.drawText(text.subSequence(start,end)+" ", 0, 2, x, y, paint);
    }
}

This works as expected and adds spacing after the spanned section. However, if I also apply a ForegroundColorSpan the color is not set for the spanned section:

EditText edit = (EditText) findViewById(R.id.edit_text);

SpannableString content = new SpannableString("1234567890");

ForegroundColorSpan fontColor = new ForegroundColorSpan(Color.GREEN);
SpacerSpan spacer = new SpacerSpan();
content.setSpan(fontColor, 0, content.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
content.setSpan(spacer, 4, 5, Spanned.SPAN_MARK_MARK);

edit.setText(content);

The Result looks like http://i.cubeupload.com/4Us5Zj.png

If I apply a AbsoluteSizeSpan the specified font size is also applied to the Replacement Span section. Is this the intended behavior, am I missing something, or a bug in android?

like image 554
Andreas Wenger Avatar asked Feb 04 '15 14:02

Andreas Wenger


1 Answers

CommonWare pointed me in the right direction. It seems like ReplacementSpans are rendered before any CharacterStyleSpan are consulted [1]

A possible (but ugly) fix is to implement a custom ForegroundColorSpan that extends MetricAffectingSpan (MetricAffectingSpans are consulted before ReplacementSpans are drawn [1]).

public class FontColorSpan extends MetricAffectingSpan {

    private int mColor;

    public FontColorSpan(int color) {
        mColor = color;
    }

    @Override
    public void updateMeasureState(TextPaint textPaint) {
        textPaint.setColor(mColor);
    }
    @Override
    public void updateDrawState(TextPaint textPaint) {
        textPaint.setColor(mColor);
    }
} 

I guess this is a bug that should be reported?

[1]http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.0.2_r1/android/text/TextLine.java#936

like image 198
Andreas Wenger Avatar answered Oct 27 '22 00:10

Andreas Wenger