Ответ 1
Если у кого-то есть эта проблема, я столкнулся с ней. Я должен был сделать второй параметр в методе setText(). Мой вызов выглядел как
textView.setText(spanned, TextView.BufferType.SPANNABLE);
Надеюсь, это поможет!
Я устанавливаю фон в строке следующим образом:
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);
К сожалению, мой метод draw() не вызывается. getSize() вызывается правильно.
Если у кого-то есть эта проблема, я столкнулся с ней. Я должен был сделать второй параметр в методе setText(). Мой вызов выглядел как
textView.setText(spanned, TextView.BufferType.SPANNABLE);
Надеюсь, это поможет!
Похоже, я нашел рабочее (но хакерское) решение этой проблемы. Попробуйте добавить еще один символ в конец строки, чтобы он не был включен в диапазон - и затем вызывается 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);
Похоже, что он игнорирует ширины целых строк.
В методе 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;
}
Даже если вы вернете ширину диапазона, высота пролета равна 0, когда диапазон охватывает всю строку. Поэтому ваш диапазон на самом деле там, с указанной шириной, но высота равна 0, поэтому не нарисована.
Вы должны установить высоту диапазона, обновляющего значения параметра Paint.FontMetricsInt fm для функции getSize. Проверьте функцию DynamicDrawable.getSize как ссылку на установку высоты, обновив значения FontMetrics.
Вызовите этот метод просмотра invalidate()
, чтобы заставить invoke на draw()
.
Я думаю, что это помогает вам. Установить textView ширину соответствия родителя. main_activity.xml
<TextView
android:width="match_parent"
Документация для ReplacementSpan.getSize() дает ответ:
Возвращает ширину промежутка. Расширяющие классы могут устанавливать высоту пролета, обновляя атрибуты Paint.FontMetricsInt. Если диапазон охватывает весь текст, а высота не задана, draw() не будет вызываться для диапазона.
Обязательно обновите Paint.FontMetricsInt
правильными значениями, чтобы решить проблему.
В моем случае я просто взял метрики из TextView
Paint
:
@Override
public int getSize(
Paint paint,
CharSequence text,
int start,
int end,
Paint.FontMetricsInt fm) {
final Paint.FontMetrics paintFontMetrics = paint.getFontMetrics();
if (fm != null) {
fm.ascent = (int) paintFontMetrics.ascent;
fm.bottom = (int) paintFontMetrics.bottom;
fm.descent = (int) paintFontMetrics.descent;
fm.leading = (int) paintFontMetrics.leading;
fm.top = (int) paintFontMetrics.top;
}
//...
}