我正在尝试使用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 RadioButton
有android:layout_width="match_parent"
答案 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);
}
}
}