私は同じような問題がありました:どのようにTextViewの左右に並んだテキストを同じ行に組み合わせるか(RadioButtonもTextViewです)。私はReplacementSpanの使い方を見つけました。
アイデアは、テキストの末尾に1つの追加シンボル(実際に描画されない)を追加し、このシンボルにあなたが何でもできるようになるReplacementSpanを付け加えます - 追加のテキストを描画する例適切な場所で(右に揃えて) ReplacementSpanでは、追加のシンボルの幅を定義できます。このスペースは分割できません。
RightAlignLastLetterSpan.attach(
textView,
"right_aligned_piece_of_text",
R.style.TextAppereance_of_your_right_aligned_text);
それは3番目の引数として与えられたスタイルでスタイルのTextViewに2番目の引数として与えられたテキストを追加します。
ので、実装の私の変種このアイデアは、このように使用することができています。追加されたテキストは右揃えになります。ここで
が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);
}
}
}
いや、私は 'AlignmentSpan'をovverridingていませんよ。 Btw、私はいくつかの組み合わせを試みたが、それは動作していません。 – rciovati