所以,在仔细研究了这个之后:https://github.com/ufo22940268/android-justifiedtextview和一般的 TextView 一样,我发现我的主要问题是我的方法。
使用缩放“ ”字符宽度的方法在理论上是合理的,但是这样做之后,线的宽度再次发生变化,因为看起来线的宽度不是其各部分的总和。
我改变了我的方法并从上面的链接中获得了灵感,因此在我的新方法中,我单独绘制每个字符,而不是绘制整条线。如果文本需要对齐(基于自定义的“justify”布尔属性),那么它将绘制线条并对齐,否则它只会绘制线条。
编辑:我现在更改了代码,以便它也支持 RTL 文本。我将在接下来的几天内将代码上传到某个地方。
Here's the result:
这是代码:
public class DTextView extends AppCompatTextView {
private boolean justify;
private float textAreaWidth;
private float spaceCharSize;
private float lineY;
public DTextView(Context context) {
super(context);
}
public DTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public DTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
/**
* @param attrs the attributes from the xml
* This function loads all the parameters from the xml
*/
private void init(AttributeSet attrs) {
TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.DTextView, 0, 0);
justify = ta.getBoolean(R.styleable.DTextView_justify, false);
ta.recycle();
}
@Override
protected void onDraw(Canvas canvas) {
drawText(canvas);
}
private void drawText(Canvas canvas) {
TextPaint paint = getPaint();
paint.setColor(getCurrentTextColor());
paint.drawableState = getDrawableState();
textAreaWidth = getMeasuredWidth() - (getPaddingLeft() + getPaddingRight());
spaceCharSize = paint.measureText(" ");
String text = getText().toString();
lineY = getTextSize();
Layout textLayout = getLayout();
if (textLayout == null)
return;
Paint.FontMetrics fm = paint.getFontMetrics();
int textHeight = (int) Math.ceil(fm.descent - fm.ascent);
textHeight = (int) (textHeight * getLineSpacingMultiplier() + textLayout.getSpacingAdd());
for (int i = 0; i < textLayout.getLineCount(); i++) {
int lineStart = textLayout.getLineStart(i);
int lineEnd = textLayout.getLineEnd(i);
float lineWidth = StaticLayout.getDesiredWidth(text, lineStart, lineEnd, paint);
String line = text.substring(lineStart, lineEnd);
if (line.charAt(line.length() - 1) == ' ') {
line = line.substring(0, line.length() - 1);
}
if (justify && i < textLayout.getLineCount() - 1) {
drawLineJustified(canvas, line, lineWidth);
} else {
canvas.drawText(line, 0, lineY, paint);
}
lineY += textHeight;
}
}
private void drawLineJustified(Canvas canvas, String line, float lineWidth) {
TextPaint paint = getPaint();
float emptySpace = textAreaWidth - lineWidth;
int spaces = line.split(" ").length - 1;
float newSpaceSize = (emptySpace / spaces) + spaceCharSize;
float charX = 0;
for (int i = 0; i < line.length(); i++) {
String character = String.valueOf(line.charAt(i));
float charWidth = StaticLayout.getDesiredWidth(character, paint);
if (!character.equals(" ")) {
canvas.drawText(character, charX, lineY, paint);
}
if (character.equals(" ") && i != line.length() - 1)
charX += newSpaceSize;
else
charX += charWidth;
}
}
}
和 XML:
<il.co.drapp.views.text.DTextView
android:layout_width="match_parent"
android:inputType="textMultiLine|textNoSuggestions"
app:justify="true"
android:id="@+id/justifyText"
android:text="@string/article_dummy_text"
android:layout_height="wrap_content" />
感谢 Aditya Vyas-Lakhan 提供的链接