具有 inter_word justificationMode 的可选 TextView
Selectable TextView with inter_word justificationMode
我正在尝试使用 justificationMode 使可选择的 TextView 合理化。
似乎这两个属性不能共存,因为当我从 TextView 中删除 android:textIsSelectable="true"
时,它就很好地证明了。
这是 TextView:
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/sf_reg"
android:padding="16dp"
android:textIsSelectable="true"
android:justificationMode="inter_word"
android:gravity="left|top"
android:textColor="@android:color/black"
android:textSize="15sp" />
我正在使用 androidx.appcompat:appcompat:1.1.0
,targetSdkVersion 是 29,minSdkVersion 是 26。
Android 自 Oreo 以来仅支持 Textview 的完全对齐,尽管我们很难使用 justificationMode 对 textview 进行对齐。
但是您可以通过在 class.
中编写一个简单的方法来实现合理化
public 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);
}
}
});
}
然后在方法中传递你的textview,
Textview tv = findviewbyid(R.id.text);
Justify(tv);
而且最棒的是,它不仅限于奥利奥,它也适用于其他较低版本的android。
android:textIsSelectable="true"
文本选择也适用于此方法。
我正在尝试使用 justificationMode 使可选择的 TextView 合理化。
似乎这两个属性不能共存,因为当我从 TextView 中删除 android:textIsSelectable="true"
时,它就很好地证明了。
这是 TextView:
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/sf_reg"
android:padding="16dp"
android:textIsSelectable="true"
android:justificationMode="inter_word"
android:gravity="left|top"
android:textColor="@android:color/black"
android:textSize="15sp" />
我正在使用 androidx.appcompat:appcompat:1.1.0
,targetSdkVersion 是 29,minSdkVersion 是 26。
Android 自 Oreo 以来仅支持 Textview 的完全对齐,尽管我们很难使用 justificationMode 对 textview 进行对齐。 但是您可以通过在 class.
中编写一个简单的方法来实现合理化public 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);
}
}
});
}
然后在方法中传递你的textview,
Textview tv = findviewbyid(R.id.text);
Justify(tv);
而且最棒的是,它不仅限于奥利奥,它也适用于其他较低版本的android。
android:textIsSelectable="true"
文本选择也适用于此方法。