首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SpannableString的问题

SpannableString的问题
EN

Stack Overflow用户
提问于 2021-06-03 20:10:02
回答 3查看 93关注 0票数 0

我花了一整天的时间才让它起作用。我以前也这样做过,但当我的驱动器崩溃时,我丢失了源代码。呼叫声:

代码语言:javascript
复制
textView.setText(getSpannableString("1Blue 2Red 5Green", false, MainActivity.this));

应将文本蓝色、红色、绿色以各自的颜色显示在文本视图中。但由于某些原因,只有" blue“中的最后一个”e“变成蓝色,"Red”中的最后一个“d”和"Green“中的最后一个”n“有正确的颜色。有人能发现我的错误吗?这个想法是在每个字符上放置一个颜色范围。

代码语言:javascript
复制
    public static SpannableString getSpannableString(String text, Boolean startWithGrey, Context context) {
    String cutText=text.replace("0","").replace("1","").replace("2","").replace("5","");
    int pos = 0;
    ForegroundColorSpan fcs;
    int colour;
    SpannableString span = new SpannableString(cutText);
    if (!startWithGrey){
        colour=0;
        fcs = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.text_colour_0));
    } else {
        colour=3;
        fcs = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.text_colour_3));
    }
    for (int i = 0; i < text.length(); i++) {
        switch (text.charAt(i)) {
            case '0':
                if (!startWithGrey){
                    colour=0;
                    fcs = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.text_colour_0));
                } else {
                    colour=3;
                    fcs = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.text_colour_3));
                }
                break;
            case '1':
                colour = 1;
                fcs = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.text_colour_1));
                break;
            case '2':
                colour = 2;
                fcs = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.text_colour_2));
                break;
            case '5':
                colour = 5;
                fcs = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.text_colour_5));
                break;
            default:
                span.setSpan(fcs, pos, pos+1 , Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                pos++;
                break;
        }
    }
    return span;
}

在color.xml中:

代码语言:javascript
复制
<color name="text_colour_0">#000000</color>
<color name="text_colour_1">#0000FF</color>
<color name="text_colour_2">#FF0000</color>
<color name="text_colour_3">#A8A8A8</color>
<color name="text_colour_5">#00FF00</color>
EN

回答 3

Stack Overflow用户

发布于 2021-06-04 13:46:30

我希望这段代码能帮助你

代码语言:javascript
复制
private SpannableString getSpannableString(String text) {

    SpannableString spannableString = new SpannableString(text);
    String[] splitString = text.split(" ");

    for (String s : splitString) {

        int startIndex = text.indexOf(s);
        int endIndex = startIndex + s.length();

        switch (s.toLowerCase()) {


            case "red":
                spannableString.setSpan(new ForegroundColorSpan(Color.RED),startIndex,endIndex,SpannableString.SPAN_INCLUSIVE_EXCLUSIVE);
                break;

            case "green" :
                spannableString.setSpan(new ForegroundColorSpan(Color.GREEN),startIndex,endIndex,SpannableString.SPAN_INCLUSIVE_EXCLUSIVE);
                break;

            case "blue":
                spannableString.setSpan(new ForegroundColorSpan(Color.BLUE),startIndex,endIndex,SpannableString.SPAN_INCLUSIVE_EXCLUSIVE);
                break;
        }

    }

    return spannableString;
}

用法::

代码语言:javascript
复制
txtview.setText(getSpannableString("Red Green Blue"));
票数 2
EN

Stack Overflow用户

发布于 2021-06-03 20:51:12

问题是因为您使用了一个循环来逐个字符地遍历,下面这一行

代码语言:javascript
复制
span.setSpan(fcs, pos, pos+1 , Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

每当它命中时,循环的所有先前数据都不会保留,所以此时循环中只有单词中的最后一个字符存在,并且这个最后一个字符应用于它的跨度。

我建议您使用SpannableStringBuilder,您可以简单地将跨度设置为整个文本,而不是逐个字符。我希望这能为你澄清一些事情。

编辑:我为此添加了一个Kotlin解决方案。由于我主要使用Kotlin,但同样可以转换为Java,因此可能需要一些研究。

代码语言:javascript
复制
fun getSpannable(inputText: String): SpannableStringBuilder {
    val splitString = inputText.split(" ")      // Split string using delimiter.
    val spanBuilder = SpannableStringBuilder()

    splitString.forEach { split ->
        val start = spanBuilder.length      // Start is the current length of the spanBuilder.
        spanBuilder.append(split.subSequence(1, split.length))      // We append a substring of our split string thus removing the number at front.
        when (split[0].toString().toInt()) {      // Extract the number at front and compare it and set span.
            1 -> spanBuilder.setSpan(ForegroundColorSpan(Color.RED), start, spanBuilder.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
            2 -> spanBuilder.setSpan(ForegroundColorSpan(Color.BLUE), start, spanBuilder.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
            3 -> spanBuilder.setSpan(ForegroundColorSpan(Color.GREEN), start, spanBuilder.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        }
    }
    return spanBuilder
}

然后,您可以按如下方式设置它

代码语言:javascript
复制
textView.setText(getSpannable("1Red 2Blue 3Green"), TextView.BufferType.SPANNABLE)
票数 1
EN

Stack Overflow用户

发布于 2021-06-08 21:31:33

好了,非常感谢你们的帮助。我不能使用你的代码片段,但它们确实帮助我理解我做错了什么。我只是一次移动一个角色的颜色范围,直到我创建了一个新的颜色范围,并一次移动了一个角色。这就是为什么每个字符中只有最后一个字符是彩色的。所以我引入了一个新的变量: start。每个颜色范围的开始。我最终得到了这个。我知道你们认为程序员可以在我使用的五分之一的代码行中做到这一点。我不是一个花哨的程序员,但至少它现在可以工作了!再次感谢!

代码语言:javascript
复制
    public static SpannableString getSpannableString(String text, Boolean startWithGrey, Context context) {
    if (text != null) {
        String cutText = text.replace("@", "").replace("%", "").replace("0", "").replace("1", "").replace("2", "").replace("3", "").replace("4", "").replace("5", "");
        text = text.replace("@", "").replace("%", "");
        int pos = 0;
        int start = 0;
        ForegroundColorSpan fcs;
        SpannableString span = new SpannableString(cutText);
        if (!startWithGrey) {
            fcs = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.text_colour_0));
        } else {
            fcs = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.text_colour_3));
        }
        for (int i = 0; i < text.length(); i++) {
            switch (text.charAt(i)) {
                case '0':
                    if (!startWithGrey) {
                        fcs = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.text_colour_0));
                    } else {
                        fcs = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.text_colour_3));
                    }
                    start = pos;
                    break;
                case '1':
                    fcs = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.text_colour_1));
                    start = pos;
                    break;
                case '2':
                    fcs = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.text_colour_2));
                    start = pos;
                    break;
                case '3':
                    fcs = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.text_colour_3));
                    start = pos;
                    break;
                case '4':
                    fcs = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.text_colour_4));
                    start = pos;
                    break;
                case '5':
                    fcs = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.text_colour_5));
                    start = pos;
                    break;
                default:
                    span.setSpan(fcs, start, pos + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    pos++;
                    break;
            }
        }
        return span;
    } else {
        return new SpannableString("");
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67821237

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档