你如何得到一个TextView的文本是正当的(与文本flush在左边和右手边)?
我在这里找到了一个可能的解决方案,但它不起作用(即使您将vertical-center更改为center_vertical等)。
你如何得到一个TextView的文本是正当的(与文本flush在左边和右手边)?
我在这里找到了一个可能的解决方案,但它不起作用(即使您将vertical-center更改为center_vertical等)。
当前回答
TextView在Android O提供了充分的理由(新的排版对齐)本身。 你只需要这样做:
科特林
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
textView.justificationMode = JUSTIFICATION_MODE_INTER_WORD
}
Java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
textView.setJustificationMode(JUSTIFICATION_MODE_INTER_WORD);
}
XML
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:justificationMode="inter_word" />
默认值是jusication_mode_none (xml中的none)。
其他回答
我找到了一个办法来解决这个问题,但是这个办法可能不是很优雅,但是效果还不错。
其原理是将每一行的空格替换为固定宽度的ImageSpan(颜色为透明)。
public static void justify(final TextView textView) {
final AtomicBoolean isJustify = new AtomicBoolean(false);
final String textString = textView.getText().toString();
final TextPaint textPaint = textView.getPaint();
final SpannableStringBuilder builder = new SpannableStringBuilder();
textView.post(new Runnable() {
@Override
public void run() {
if (!isJustify.get()) {
final int lineCount = textView.getLineCount();
final int textViewWidth = textView.getWidth();
for (int i = 0; i < lineCount; i++) {
int lineStart = textView.getLayout().getLineStart(i);
int lineEnd = textView.getLayout().getLineEnd(i);
String lineString = textString.substring(lineStart, lineEnd);
if (i == lineCount - 1) {
builder.append(new SpannableString(lineString));
break;
}
String trimSpaceText = lineString.trim();
String removeSpaceText = lineString.replaceAll(" ", "");
float removeSpaceWidth = textPaint.measureText(removeSpaceText);
float spaceCount = trimSpaceText.length() - removeSpaceText.length();
float eachSpaceWidth = (textViewWidth - removeSpaceWidth) / spaceCount;
SpannableString spannableString = new SpannableString(lineString);
for (int j = 0; j < trimSpaceText.length(); j++) {
char c = trimSpaceText.charAt(j);
if (c == ' ') {
Drawable drawable = new ColorDrawable(0x00ffffff);
drawable.setBounds(0, 0, (int) eachSpaceWidth, 0);
ImageSpan span = new ImageSpan(drawable);
spannableString.setSpan(span, j, j + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
builder.append(spannableString);
}
textView.setText(builder);
isJustify.set(true);
}
}
});
}
我把代码放在GitHub上: https://github.com/twiceyuan/TextJustification
概述:
XML布局:声明WebView而不是TextView
<WebView
android:id="@+id/textContent"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
Java代码:设置文本数据到WebView
WebView view = (WebView) findViewById(R.id.textContent);
String text;
text = "<html><body><p align=\"justify\">";
text+= "This is the text will be justified when displayed!!!";
text+= "</p></body></html>";
view.loadData(text, "text/html", "utf-8");
这也许能解决你的问题。 它完全为我工作。
你可以在xml中使用rationationmode作为inter_word。您必须记住,此属性可用于api级别26及更高级别。为此,你可以将targetApi赋值为o。完整的代码如下所示
<com.google.android.material.textview.MaterialTextView
...
android:justificationMode="inter_word"
tools:targetApi="o" />
我不认为Android支持完全的理由。
更新2018-01-01:Android 8.0+支持TextView对齐模式。
FILL_HORIZONTAL等价于CENTER_HORIZONTAL。 你可以在textview的源代码中看到这个代码片段:
case Gravity.CENTER_HORIZONTAL:
case Gravity.FILL_HORIZONTAL:
return (mLayout.getLineWidth(0) - ((mRight - mLeft) -
getCompoundPaddingLeft() - getCompoundPaddingRight())) /
getHorizontalFadingEdgeLength();