3

我正在尝试制作一款游戏来帮助孩子们学习数学。我为代码编号着色,以便他们可以遵循逻辑。我还使用 textView.append() 构建一个长字符串以放入活动中。

因为我在指令中重复使用相同的数字/符号,所以我想要一种轻松回收 SpannableStrings 的方法,但似乎我所做的更改第一次正确应用,但此后有时有效,有时部分有效(例如正确的大小/alignment,但颜色错误),或者根本不工作。我得到了这一切的混合。我似乎在 Stackoverflow 或 Google 的其他任何地方都找不到遇到类似问题的人。

这是我的代码(简化):

    // Declare static variables
    public static Spannable PLUS = new SpannableString("+ ");
    public static Spannable MINUS = new SpannableString("- ");
    public static Spannable TIMES = new SpannableString("X ");
    public static Spannable DIVIDED_BY = new SpannableString("/ ");
    public static Spannable EQUALS = new SpannableString("= ");

    // Function to color these strings.
    public void colorStrings() {
    makeBlack(PLUS);
    makeBlack(MINUS);
    makeBlack(TIMES);
    makeBlack(DIVIDED_BY);
    makeBlack(EQUALS);
    makeBlack(QMARK);
    }

    // Function that actually sets color, size, and alignment.
    public Spannable makeBlack(Spannable s) {s.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.color_black)), 0, s.length()-1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    s.setSpan(new AbsoluteSizeSpan((int) getResources().getDimension(R.dimen.big_text)), 0, s.length()-1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    s.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER), 0, s.length()-1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    return s;
    }

    // Implementing above code by setting math1 TextView to give it colors.
    // Note that this is the exact code used for the first colored string in the
    // screen capture below.
    math1.setText(XX);
    math1.append(PLUS);
    math1.append(YY);
    math1.append(PLUS);
    math1.append(ZZ);
    math1.append(EQUALS);
    math1.append(QMARK);

(请注意,我没有提供 XX、YY 或 ZZ 的代码……这有点复杂,因为我必须从 sharedpreference 设置中获取数据,但这些问题与其他数学符号基本相同/运营商)。

这是生成的屏幕截图:

在此处输入图像描述

也许我的问题最好的例子是+(加号)。起初,它是预期的黑色,但只有 4 个字符后(包括空格)它是错误的颜色(蓝色,它可能来自之前的 SpannableString),尽管对齐和大小正确。在下一个彩色字符串中,它按预期显示(黑色、居中、大),但之后在随后的“彩色”字符串(小、左对齐、绿色,如段落文本)中根本没有格式化。使用的代码看起来与上面完全相同(即 math1.append(PLUS);),但输出与我预期的不一致。

最后一条信息:在全局声明我的变量之前,我每次都使用相同的 makeBlack() 和 math1.append() 函数在本地声明它们,并且效果很好。在全局设置我的变量后,我只会得到这种奇怪的行为。

关于这里出了什么问题的任何建议?

4

4 回答 4

8

您不能多次重复使用相同的跨度。即使跨度完全相同,您也需要为要更改的字符串的每个部分创建一个唯一的跨度。

我不确定我在哪里读到这个,但我可以确认答案。

为您想要更改的每一件事创建一个独特的跨度。

于 2013-11-19T18:41:34.093 回答
5

可以多次使用相同的跨度,使用

CharacterStyle.wrap(CharacterStyle c)

每次您需要使用相同的 Span 时,将其作为参数传递。

于 2014-02-23T18:46:59.023 回答
3

只是想插话,因为我遇到了同样的问题。如果您深入研究一个Spannable类,例如SpannableStringBuilder,那么您为什么不能重用Span. 设置跨度时,将执行此块:

for (int i = 0; i < count; i++) {
    if (spans[i] == what) {
        int ostart = mSpanStarts[i];
        int oend = mSpanEnds[i];

        if (ostart > mGapStart)
            ostart -= mGapLength;
        if (oend > mGapStart)
            oend -= mGapLength;

        mSpanStarts[i] = start;
        mSpanEnds[i] = end;
        mSpanFlags[i] = flags;

        if (send) sendSpanChanged(what, ostart, oend, nstart, nend);

        return;
    }
}

基本上,这段代码遍历现有的跨度,与设置的跨度进行比较,如果匹配,则更新跨度边界。防止if (spans[i] == what)成为真的唯一方法是传入一个新的跨度实例。

于 2015-10-09T20:26:50.607 回答
1

不应重复使用 Span 对象。我之前也遇到过类似的问题。

于 2013-11-19T17:39:11.197 回答