2015-02-04 3 views
4

Я пытаюсь использовать ReplacementSpans форматировать вход в EditText поле (без изменения содержания):ForegroundColorSpan не применяется к ReplacementSpan

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

Это работает, как ожидалось, и добавляет интервал после пролетных секции. Однако, если я также применить ForegroundColorSpan цвета не установлен для пролетных секции:

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

Результат выглядит как http://i.cubeupload.com/4Us5Zj.png

Если я применяю AbsoluteSizeSpan указанного размера шрифта также применяются к замене Пространство. Является ли это предполагаемым поведением, я что-то упускаю, или ошибка в андроиде?

+0

Поскольку только конкретные реализации 'ReplacementSpan' в SDK является для замены текста с изображениями, это может быть, что этот материал не был проверен все, что хорошо для замены текста с большим количеством текста , Одно отличие между «ForegroundColorSpan» и «AbsoluteSizeSpan» заключается в том, что последний переопределяет как «updateMeasureState()», так и «updateDrawState()», а «ForegroundColorSpan» только переопределяет «updateDrawState()». Это имеет смысл, поскольку цвет переднего плана не влияет на измерения. Однако возможно, что 'Paint', переданный в' draw() ', неверен. – CommonsWare

+0

Да, кажется, что '' '' '' '' '', который передается '' 'draw()' '', является другим (выход, если я регистрирую установленную краску): '' 'ForegroundColor. r: 0, g: 255, b: 0''' '' 'Цвет во время розыгрыша. r: 0, g: 0, b: 0''' –

+0

В качестве теста вы можете попробовать создать подкласс 'ForegroundColorSpan', который переопределяет' updateMeasureState() ', чтобы делать то, что делает' updateDrawState() ', а затем попробуйте применить ваши подкласс вместо 'ForegroundColorSpan'. Если ваш подкласс работает, хорошей новостью является то, что вы наверняка узнаете источник проблемы. Плохая новость заключается в том, что вы можете потерять свой подкласс, если 'Spanned' передается через' Bundle', поскольку для этого AFAIK поддерживаются только встроенные 'ParcelableSpans'. – CommonsWare

ответ

4

CommonWare указал мне в правильном направлении. Похоже ReplacementSpans оказываются перед любым CharacterStyleSpan консультируются [1]

Возможным (но некрасиво) исправление для реализации пользовательского ForegroundColorSpan, который расширяет MetricAffectingSpan (MetricAffectingSpans проводятся консультации до того ReplacementSpans рисуются [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); 
    } 
} 

Я думаю, это ошибка, о которой следует сообщить?

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

+1

Это также объясняет, почему был применен '' 'AbsoluteSizeSpan''' (он расширяет' 'MetricAffectingSpan''') –

Смежные вопросы