ReplacementSpan不在棉花糖中工作

时间:2016-12-06 07:13:36

标签: android textview spannablestring

我使用ReplacementSpan为TextView添加了Text Stroke。它在Marshmallow下面的Android Sdk中完美运行。但是,在棉花糖中它显示空白文本。当我将ForegroundSpan添加到Top 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);

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

实施LineHeightSpan(按照vovahost的回答)并不总是可以正常工作。高度有时会计算不正确,导致文本被剪切在顶部。

一种可能的解决方法是让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);