ReplacementSpan не работает в Marshmallow



Я добавил текстовый штрих для TextView, используя ReplacementSpan. Он отлично работает в Android Sdk ниже Marshmallow. Но, в зефире он показывает пустой текст. Когда я еще добавил ForegroundSpan в верхнем поле TextView, а затем установить обычай мой пролет под видом его работы. Я не понимаю, я что-нибудь не хватает.

Ниже приведен мой TextSpannable код класса -



public class TextSpannable extends ReplacementSpan {

private final Paint paintFill = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint paintStroke = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Path path = new Path();
private int width;

public TextSpannable(int strokeWidth) {
paintFill.setColor(Color.WHITE);
paintStroke.setStyle(Paint.Style.STROKE);
paintStroke.setStrokeWidth(6);
}

public void setPathEffect(PathEffect effect) {
paintStroke.setPathEffect(effect);
}

@Override
public int getSize(Paint paint, CharSequence text, int start,
int end, Paint.FontMetricsInt fm) {
this.paintFill.setColor(Color.WHITE);
this.paintStroke.setColor(Color.parseColor("#402002"));
width = (int) (paint.measureText(text, start, end) +
this.paintStroke.getStrokeWidth() + paintFill.getTextSize());
return width;
}

@Override
public void draw(Canvas canvas, CharSequence text, int start, int end,
float x, int top, int y,int bottom, Paint paint) {
path.reset();
paint.getTextPath(text.toString(), start, end, x, y, path);
path.close();

canvas.translate(this.paintStroke.getStrokeWidth() / 2, 0);
canvas.drawPath(path,this.paintStroke);
canvas.drawPath(path, this.paintFill);
canvas.translate(-this.paintStroke.getStrokeWidth() / 2, 0);
//canvas.drawText(this.text,start,end,x,y,paintFill);
//canvas.drawText(this.text,start,end,x,y,paintStroke);
}
}


Вот как я установил его в TextView -



    spannableString7 = 
new SpannableStringBuilder(getString(R.string.string1));
ForegroundColorSpan fcs =new ForegroundColorSpan(Color.TRANSPARENT);
spannableString7.setSpan(fcs,0, getString(R.string.string1).length(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textSpam.setText(spannableString7, TextView.BufferType.SPANNABLE);

//when I comment above block, text becomes blank in Textview

spannableString1 =
new SpannableStringBuilder(getString(R.string.string1));
spannableString1.setSpan(textSpannable,0,getString(R.string.string1).length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString1, TextView.BufferType.SPANNABLE);
483   2  

2 ответов:

Я придумал, как заставить его работать. Вы должны реализовать LineHeightSpan, потому что если вы используете ReplacementSpan сам по себе, то я полагаю, что TextView не знает, какую высоту имеет ваш текст ? Просто реализация LineHeightSpan исправит проблему.

public class CoolBackgroundColorSpan extends ReplacementSpan implements LineHeightSpan {

    @Override
    public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
        // Your code here
    }

    @Override
    public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
        // Your code here
    }

    @Override
    public void chooseHeight(CharSequence charSequence, int i, int i1, int i2, int i3, Paint.FontMetricsInt fontMetricsInt) {
        // This method is needed because the class implements LineHeightSpan.
        // We don't modify the fontMetricsInt because we don't want to modify the line height.
        // The line height will have the height of the text
    }

}

Если вы также хотите изменить высоту строки, то смотрите этот ответ https://stackoverflow.com/a/39044426/1502079 .

Реализация LineHeightSpan (согласно ответу вовахоста) не всегда работает правильно. Высота иногда вычисляется неправильно, в результате чего текст вырезается сверху.

Возможный обходной путь состоит в том, чтобы SpannableStringBuilder содержал что-то еще, а не просто ReplacementSpan. К тексту можно добавить пробел нулевой ширины, чтобы он выглядел неизменным, но правильно измерялся и отображался с помощью TextView, например:

spannableString1 = 
    new SpannableStringBuilder(getString(R.string.string1));
spannableString1.setSpan(textSpannable,0,getString(R.string.string1).length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

spannableString1.append('\u200B'); // <-- append a zero-width space

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

Comments

    Ничего не найдено.