2013-11-19 2 views
10

я поставил фон в строке так:Жеребьевки ReplacementSpan (в) не называется

spanString.setSpan(new BackgroundColorSpan(color), 0, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 

Но я хотел бы, чтобы увеличить левые и правые отступы на этом фоне, поэтому я создал пользовательский промежуток

public class PaddingBackgroundSpan extends ReplacementSpan { 
private int mBackgroundColor; 
private int mForegroundColor; 

public PaddingBackgroundSpan(int backgroundColor, int foregroundColor) { 
    this.mBackgroundColor = backgroundColor; 
    this.mForegroundColor = foregroundColor; 
} 

@Override 
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { 
    return Math.round(measureText(paint, text, start, end)); 

} 

@Override 
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { 
    RectF rect = new RectF(x, top, x + measureText(paint, text, start, end), bottom); 
    paint.setColor(mBackgroundColor); 
    canvas.drawRect(rect, paint); 
    paint.setColor(mForegroundColor); 
    canvas.drawText(text, start, end, x, y, paint); 
} 

private float measureText(Paint paint, CharSequence text, int start, int end) { 
    return paint.measureText(text, start, end); 
} 

Я использую свой срок по:

spanString.setSpan(new PaddingBackgroundSpan(color1, color2), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 

К сожалению, метод мой ничья() не вызывается. getSize() вызывается правильно.

ответ

0

Вызвать этот метод вида invalidate(), чтобы заставить invoke на draw().

+0

Я не хочу, чтобы сделать беспорядок на уровне представления, я хочу Span, которые делают отступы по себе, как со стандартным BackgroundColorSpan. Является ли это возможным? [EDIT] Я только что проверил Ваше решение. Вызовите invalidate в TextView после добавления SpannableString (это ваше предложение?), И оно не работает. – qbait

15

Если у кого-то возникла эта проблема, я столкнулся с ней. Я должен был сделать второй параметр в методе setText(). Мой звонок выглядел как

textView.setText(spanned, TextView.BufferType.SPANNABLE); 

Надеюсь, это поможет!

+0

Должно быть принято как ответ. Работа для меня –

+0

Это не работает для меня. –

+0

не работает для меня –

3

Похоже, я нашел рабочее (но хакерское) решение этой проблемы. Попытайтесь добавить еще один символ в конец строки, чтобы он не включался в диапазон, а затем вызывается draw()!

char EXTRA_SPACE = ' '; 
String text = originalString + EXTRA_SPACE; 
Spannable spannable = new SpannableString(text); 
spannable.setSpan(new MyReplacementSpan(), 0, text.length()-1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); 
textView.setText(spannable); 

Похоже, что он игнорирует пролеты шириной целых.

+0

Этот вид волшебства работает для меня! Спасибо огромное! – CatCap

2

Даже если вы вернете ширину пролета, высота пролета равна 0, когда диапазон охватывает всю строку. Поэтому ваш диапазон на самом деле там, с указанной шириной, но высота равна 0, поэтому не нарисована.

Вы должны установить высоту пролета обновляя значения параметра Paint.FontMetricsInt фм для функции GETSIZE. Проверьте функцию DynamicDrawable.getSize как ссылку, чтобы установить высоту, обновив значения FontMetrics.

2

В методе getSize()Paint.FontMetricsInt fm должны быть пересчитаны на paint FontMetricsInt:

@Override 
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { 
    width = Math.round(paint.measureText(text, start, end)); 
    Paint.FontMetricsInt metrics = paint.getFontMetricsInt(); 
    if (fm != null) { 
     fm.top = metrics.top; 
     fm.ascent = metrics.ascent; 
     fm.descent = metrics.descent; 

     fm.bottom = metrics.bottom; 
    } 
    return width; 
}