在Android中更改跨度内的文本时删除跨度

Posted

技术标签:

【中文标题】在Android中更改跨度内的文本时删除跨度【英文标题】:Remove span when text inside the span is changed in Android 【发布时间】:2018-01-21 17:39:32 【问题描述】:

假设我发表了这样的评论: 嗨,安德里亚,看看这个.....在那条评论中我想突出显示安德里亚,但每当我更改安德里亚的值或当我删除单词的一个字符时,跨度会发生变化,问题是我正在使用@987654321 @,其中Spanned.SPAN_EXCLUSIVE_EXCLUSIVE接受中间词和删除词,当用户改变词或删除词的一个字符时如何去除span?

【问题讨论】:

小提琴或代码将有助于回答这个问题。 【参考方案1】:

您可以为此尝试TextWatcher,只需将TextWatcher添加到您想要在上面实现的textview中

 @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) 
//Do some magic here
    

现在,每当用户键入或删除任何字符时,您都会在此方法中收到回调,在收到您可以重置您的跨度时。

【讨论】:

解释了基本的想法是在此处实现文本更改的回调。【参考方案2】:

如果您使用SpannableString,您必须在每次更改时重新创建整个内容。

您可以删除跨度,但不能更改源(注释),因为SpannableString 源文本是不可变的。

我建议在每次更改评论时创建SpannableString,查找名称并标记它们,然后如果评论发生更改,您使用新的SpannableString 重复相同的操作。不会有性能问题,因为 cmets 体积小。

如果你想拥有一个可变对象,你可以使用SpannableStringBuilder,但它更复杂,没有必要。

【讨论】:

【参考方案3】:

您需要注意编辑文本上的文本更改。 假设您使用的EditText 命名为commentEditText

 commentEditText.addTextChangedListener(new TextWatcher() 
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) 

            

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) 

            

            @Override
            public void afterTextChanged(Editable editable) 
                String comment = editable.toString();
                if (comment.indexOf('@') != -1) 
                    //Asumming the name string
                    String name = "Andrea";
                    int atIndex = comment.indexOf('@');
                    int endIndex = atIndex + name.length() + 1;
                    if (endIndex == -1 || endIndex > editable.length()) 
                        endIndex = editable.length();
                    
                    if (comment.toLowerCase().contains(name.toLowerCase())) 
                        editable.setSpan(new StyleSpan(Typeface.BOLD), atIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                     else 
                        StyleSpan[] spannable = editable.getSpans(atIndex, endIndex, StyleSpan.class);
                        if (spannable != null && spannable.length > 0) 
                            for (int i = 0; i < spannable.length; i++) 
                                editable.removeSpan(spannable[i]);
                            
                        

                    
                
            
        );

【讨论】:

以上是关于在Android中更改跨度内的文本时删除跨度的主要内容,如果未能解决你的问题,请参考以下文章

跨度内的文本将按钮向右推[重复]

无法更改图像标签内的跨度高度和宽度

将字体真棒跨度图标放置在锚点内的文本上方

更改跨度文本? [复制]

限制按钮内的跨度大小

在 Javascript 中使用跨度和符号更改 HTML [重复]