3

子供たちが数学を学ぶのを助けるゲームを作ろうとしています。番号を色分けして、ロジックに従うことができるようにします。また、textView.append() を使用して、アクティビティに入れる長い文字列を作成します。

命令で同じ数字/記号を再利用するため、SpannableStrings を簡単にリサイクルする方法が必要でしたが、行った変更は最初は正しく適用されているようですが、その後は機能することもあれば、部分的に機能することもあります (正しいサイズなど)。 /alignment, but wrong color)、またはまったく機能しません。私はそれをすべて混ぜ合わせています。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 のコードを提供しなかったことに注意してください...共有設定からデータを取得する必要があるため、もう少し複雑ですが、これらは他の数学記号と本質的に同じ問題を経験します/オペレーター)。

これは結果のスクリーン キャプチャです。

ここに画像の説明を入力

おそらく、私の問題の最も良い例は + (プラス記号) です。最初は予想どおり黒ですが、4 文字 (スペースを含む) だけで間違った色 (以前の SpannableString から取得した可能性が高い青) になりますが、配置とサイズは正しくなっています。次の色付き文字列では、期待どおりに表示されます (黒、中央揃え、大) が、その後の「色付き」文字列 (小、左揃え、緑、段落テキストのように) ではまったく書式設定されていません。使用されたコードは上記とまったく同じように見えます (つまり、math1.append(PLUS);) が、出力は一貫して私が期待したものではありません。

最後の情報: 変数をグローバルに宣言する前に、毎回同じ makeBlack() 関数と math1.append() 関数を使用して変数をローカルに宣言しましたが、完全に機能しました。変数をグローバルに設定した後にのみ、この奇妙な動作が発生します。

ここで何がうまくいかないのかについての提案はありますか?

4

4 に答える 4

8

同じスパンを複数回再利用することはできません。スパンがまったく同じであっても、変更する文字列のセクションごとに一意のスパンを作成する必要があります。

これをどこで読んだかわかりませんが、答えを確認できます。

変更したいものごとに固有のスパンを作成します。

于 2013-11-19T18:41:34.093 に答える
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;
    }
}

基本的に、このコードは既存のスパンをループし、設定されているスパンと比較し、一致する場合はスパンの境界を更新します。trueにならないようにする唯一の方法if (spans[i] == what)は、スパンの新しいインスタンスを渡すことです。

于 2015-10-09T20:26:50.607 に答える
1

Span オブジェクトは再利用しないでください。以前も同様の問題がありました。

于 2013-11-19T17:39:11.197 に答える