setSpan()删除了Android Lollipop API 21上的其他范围

时间:2019-06-29 19:01:08

标签: android android-edittext spannable android-textinputedittext

类似于this question,我有一个加粗按钮,单击该按钮可以在键入EditText时启用粗体样式,再次按下时将禁用粗体样式。

在Android API 26和24上运行正常:

“ regularText 粗体 regularTextAgain”

在上面的示例中,在键入“ regularText”之后,我按下了粗体按钮并键入了“ Boldtext”,在 Boldtext 之后,我再次了按下并键入了“ regularTextAgain”

注意单词之间没有空格。

在API 21上,它的行为不同:

在键入“ regularText Boldtext ”后按粗体按钮禁用样式时,下一个字符没有粗体样式,但是 BoldText 上的粗体样式也消失了!

这是我的TextWatcher

class RichTextWatcher implements android.text.TextWatcher {
    private int mStartPos;
    private int mEndPos;

    RichTextWatcher() {
        mStartPos = 0;
        mEndPos = 0;
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        mStartPos = start + count;
        mEndPos = start + count + 1;
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable s) {
        if (mStyleListener == null) {
            Log.e("RichTextWatcher", "style listener is null");
            return;
        }
        for (MarkdownStyleSpan styleSpan : mStyleListener.getActiveStyles()) {
            styleSpan.getStylePainter().applyStyle(s, mStartPos, mEndPos);
        }
    }
}

这是我应用粗体样式的方式:

public class BoldStylePainter implements IStylePainter {
    private int mStartPos = -1;

    @Override
    // called when enabling the bold style
    public void applyStyle(@NonNull Editable s, int start, int end) {
        if (end > s.length() || start < 0) {
            return;
        }
        mStartPos = mStartPos < 0 ? start : mStartPos;
        if (end >= mStartPos) {
            s.setSpan(getBoldSpan(), mStartPos, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
    }

    @Override
    // called when disabling the bold style
    public void removeStyle(@NonNull Editable s, int start, int end) {
        mStartPos = -1;
    }

    private StyleSpan getBoldSpan() {
        return new StyleSpan(Typeface.BOLD);
    }
}

我不理解这种行为,尤其是相同的代码可以按预期在API 24和26上工作。知道发生了什么吗?

注意,关于API 21的beforeTextChanged(...)onTextChanged(...)start索引始终为零,除非按下空格,但是count具有索引,因此我必须计算开始和结束索引,以使其在所有API中都匹配。

0 个答案:

没有答案