Android - 当部分删除时删除整个ImageSpan?

时间:2014-05-15 00:21:50

标签: android image android-edittext

我通过插入ImageSpan将图像添加到我的edittext中。我对跨度没有彻底的了解,但似乎我的ImageSpan需要包装一部分文本。所以我在EditText中添加了一些文本,并用ImageSpan包装它,看起来很好。但是,当我退格ImageSpan时,它只删除文本的一个字符,图像将保留,直到整个文本被删除。如何使用一个退格键删除它?

SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append(content.getText());

String imgId = "[some useful text]"; 

int selStart = content.getSelectionStart();

builder.replace(content.getSelectionStart(), content.getSelectionEnd(), imgId);

builder.setSpan(imageSpan, selStart, selStart+imgId.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
content.setText(builder);

3 个答案:

答案 0 :(得分:7)

过了一段时间,我找到了解决方案。试试这段代码:

private TextWatcher watcher = new TextWatcher() {
    private int spanLength = -1;

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        if (start == 0) return;
        if (count > after) {
            ImageSpan[] spans = getEditableText().getSpans(start + count, start + count, ImageSpan.class);
            if (spans == null || spans.length == 0) return;
            for (int i = 0; i < spans.length; i++) {
                int end = getEditableText().getSpanEnd(spans[i]);
                if (end != start + count) continue;
                String text = spans[i].getSource();
                spanLength = text.length() - 1;
                getEditableText().removeSpan(spans[i]);
            }
        }
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if (spanLength > -1) {
            int length = spanLength;
            spanLength = -1;
            getEditableText().replace(start - length, start, "");
        }
    }

    @Override
    public void afterTextChanged(Editable s) {
    }
};

但是您应该使用原始字符串创建ImageStan,如下所示:

ssb.setSpan(new ImageSpan(bmpDrawable, originalStr), x, x + originalStr.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

答案 1 :(得分:0)

这是我的刺刀

field.doBeforeTextChanged { text, start, count, _ ->
            val spans = toField.text.getSpans<ImageSpan>(start = start + 1, end = start + 1 + count)
            for (span in spans) {
                toField.text.removeSpan(span)
            }
        }

请不要忘记将ImageSpan替换为您感兴趣的那个。

答案 2 :(得分:0)

以上回答很有用。但请注意:imagespan.source 用于在构建图像时保存有关图像 uri 的信息! 当您使用 ImageSpan 时,mSource 被赋予连接到其 uri 的可绘制资源的字符串值 在 Api 30 及更高版本中使用 contentDescription 或者这样做可能会有所帮助

private val watcher: TextWatcher = object : TextWatcher {
    override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
        if(s.isEmpty()) return
        // delete operation
        // from position 'start'
        // the tail of 's',with length 'count' would be erased 
        // for ime input reason, 'count' is always 1
        if(count>after){
            val spans: Array<ImageSpan> = article_publish_content.text.getSpans(
                0, start + count,
                ImageSpan::class.java
            )
            if (spans.isEmpty()) return
            // here sometimes you could use spans[spans.indices-1]
            // to reduce no-need traversal
            for (i in spans.indices) {
                val spanEnd: Int = article_publish_content.text.getSpanEnd(spans[i])
                val spanStart=article_publish_content.text.getSpanStart(spans[i])
                if (spanEnd != start + count) continue
                spanLength = spanEnd-spanStart
                article_publish_content.text.removeSpan(spans[i])
            }
        }
    }

    override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
        if (spanLength > -1) {
            val length = spanLength
            spanLength = -1
            var oStart=start-length
            if(oStart<0)
                oStart=0
            article_publish_content.text.replace(oStart, start, "")
        }
    }

    override fun afterTextChanged(s: Editable) {

    }
}