AlignmentSpan不适用于RadioButton文本

时间:2013-11-21 16:51:45

标签: android

我正在尝试使用RadioButton类与AlignmentSpan文本的右侧对齐。但是它无法正常工作,因为文本未按预期对齐。

SpannableStringBuilder builder = new SpannableStringBuilder();

builder.append(option.getLabel());

int start = builder.length() + 1;

builder.append(" ");
builder.append(price);
builder.append("€");

int end = builder.length();

builder.setSpan(new AlignmentSpan.Standard(Alignment.ALIGN_OPPOSITE), start, end,
        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

final StyleSpan bss = new StyleSpan(android.graphics.Typeface.BOLD);

builder.setSpan(bss, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

从代码中我可以看到,我还应用了StyleSpan,它可以正常工作。

N.B RadioButtonandroid:layout_width="match_parent"

3 个答案:

答案 0 :(得分:2)

随机建议,可能有效或无效,但是......您是否尝试在字符串中注入Unicode控制字符? (不正确)使用诸如U + 200E,U + 200F,U + 202A ... U + 202E之类的字符,您可以说服文本渲染器它们是RTL与LTR混合的部分。不确定这是否有帮助,你可能需要在分开的段落中包含东西,但这是我现在唯一能想到的。

答案 1 :(得分:2)

尝试android:layout_width="_wrap_content"一次。

试试这个并告诉我结果....

final StyleSpan bss = new StyleSpan(android.graphics.Typeface.BOLD);

builder.setSpan(bss, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    int end = builder.length();

builder.setSpan(new AlignmentSpan.Standard(Alignment.ALIGN_OPPOSITE), start, end,
        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

如果我没错,你会覆盖你最初设定的范围。所以尽量一起设置跨度。

答案 2 :(得分:0)

我遇到了类似的问题:如何在TextView中将左右对齐文本放在同一行中(RadioButton也是TextView)。我找到了使用ReplacementSpan的方法。

这个想法是在文本的末尾添加一个额外的符号(它不会被实际绘制)并将此符号附加到您的ReplacementSpan,您可以在其中执行任何操作 - 例如绘制其他符号文本在适当的位置(与右对齐)。 ReplacementSpan允许定义附加符号的宽度,这个空间将是牢不可破的。

所以,我的实现变体这个想法可以像这样使用:

RightAlignLastLetterSpan.attach(
                        textView,
                        "right_aligned_piece_of_text",
                        R.style.TextAppereance_of_your_right_aligned_text);

它将作为第二个参数的文本添加到 textView 样式,其样式为第三个参数。添加的文本将右对齐。

以下是RightAlignLastLetterSpan的完整来源:

class RightAlignLastLetterSpan extends ReplacementSpan {

    @SuppressWarnings("FieldCanBeLocal") private static boolean DEBUG = false;

    private float textWidth = -1;
    @Nullable private TextAppearanceSpan spanStyle;
    @Nullable private String text;
    @NonNull private TextView tv;

    protected RightAlignLastLetterSpan(@NonNull TextView tv) {this.tv = tv;}

    public static boolean attach(@Nullable TextView tv, @Nullable String text, @StyleRes int resourceTextAppearance) {

        if (tv == null || isEmpty(text)) {
            logWrongArg();
            return false;
        }

        RightAlignLastLetterSpan span = new RightAlignLastLetterSpan(tv);
        span.setSpanStyle(new TextAppearanceSpan(tv.getContext(), resourceTextAppearance));
        span.setText(text);

        SpannableString ss = new SpannableString(new StringBuffer(tv.getText()).append(" _"));
        ss.setSpan(span, ss.length() - 1, ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        tv.setText(ss);

        return true;
    }

    public void setSpanStyle(@Nullable TextAppearanceSpan spanStyle) {

        textWidth = -1;
        this.spanStyle = spanStyle;
    }

    public void setText(@Nullable String text) {

        textWidth = -1;
        this.text = text;
    }

    @Override
    public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {

        if (textWidth < 0) {
            applyStyle(paint);
            textWidth = isEmpty(this.text) ? 0 : paint.measureText(this.text);
        }

        return Math.round(textWidth);
    }

    @Override
    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {

        if (textWidth == 0 || this.text == null) {
            return;
        }

        int lineCount = tv.getLineCount();
        if (lineCount < 1) {return;}

        Rect lineBounds = new Rect();
        int baseline = tv.getLineBounds(lineCount - 1, lineBounds);
        lineBounds.offset(-tv.getPaddingLeft(), -tv.getPaddingTop());
        baseline -= tv.getPaddingTop();

        if (DEBUG) {
            paint.setColor(Color.argb(100, 100, 255, 100));
            canvas.drawRect(lineBounds, paint);

            paint.setColor(Color.argb(100, 255, 100, 100));
            canvas.drawRect(x, top, x + textWidth, bottom, paint);
        }

        applyStyle(paint);

        canvas.drawText(this.text, lineBounds.right - textWidth, baseline, paint);
    }

    public void applyStyle(Paint paint) {

        if (paint instanceof TextPaint && spanStyle != null) {
            TextPaint tp = (TextPaint) paint;
            spanStyle.updateDrawState(tp);
        }
    }
}