【发布时间】:2017-11-06 04:35:37
【问题描述】:
所以,正如你们大多数人所知,Android 中的 TextView 中没有文本对齐。因此,我构建了一个自定义 TextView 来解决这个问题。但是,由于某种原因,有时标点符号会在某些设备中因某种原因而中断。我在 LG G3 和模拟器(运行最新版本的 Nexus 4)和逗号“,”上进行了测试,例如在 LG G3 上打破了理由,但在模拟器上没有。
如果我添加至少为 2 的 Padding start 和 end(或 left 和 right),问题就解决了。这在我看来很随意。
基本上,我的逻辑是,为了证明文本的合理性,我需要知道 TextView 本身的宽度,将文本构造成最大长度的行。然后,通过查找行中的空格数和剩余的空白空间,根据剩余像素(或视图中的空间)拉伸要缩放的“”(空格)字符。
它工作得几乎完美,而且大多数时候它也支持 RTL 文本。
这里有一些带有和不带有违规标记的文本图片(一个简单的 lorem impsum)(第一个是在运行 7.1.1 的模拟器 nexus 4 上,第二个是在运行 v5.0 的 LG G3 上)
代码如下:
public class DTextView extends AppCompatTextView {
private boolean justify;
public DTextView(Context context) {
super(context);
}
public DTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public DTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
private void setJustify(boolean justify) {
this.justify = justify;
if (justify) {
justify();
}
}
private void init(@Nullable AttributeSet attrs) {
TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.DTextView, 0, 0);
justify = ta.getBoolean(R.styleable.DTextView_justify, false);
ta.recycle();
}
private SpannableStringBuilder justifyText() {
String[] words = getText().toString().split(" ");
setText("");
int maxLineWidth = getWidth() - getPaddingLeft() - getPaddingRight();
SpannableStringBuilder justifiedTextSpannable = new SpannableStringBuilder();
//This will build the new text with the lines rearranged so that they will have a width
//bigger than the View's own width
ArrayList<String> lines = new ArrayList<>(0);
String line = "";
for (String word : words) {
if (getWordWidth(line + word) < maxLineWidth) {
line += word + " ";
} else {
line = line.substring(0, line.length() - 1);
lines.add(line);
line = word + " ";
}
}
//Add the last line
lines.add(line);
for (int i = 0; i < lines.size() - 1; i++) {
justifiedTextSpannable.append(justifyLine(lines.get(i), maxLineWidth));
justifiedTextSpannable.append("\n");
}
justifiedTextSpannable.append(lines.get(lines.size() - 1));
return justifiedTextSpannable;
}
private SpannableString justifyLine(String line, float maxWidth) {
SpannableString sLine = new SpannableString(line);
float spaces = line.split(" ").length - 1;
float spaceCharSize = getWordWidth(" ");
float emptySpace = maxWidth - getWordWidth(line);
float newSpaceSize = (emptySpace / spaces) + spaceCharSize;
float scaleX = newSpaceSize / spaceCharSize;
for (int i = 0; i < line.length(); i++) {
if (line.charAt(i) == ' ') {
sLine.setSpan(new ScaleXSpan(scaleX), i, i + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
return sLine;
}
private void justify() {
justify = false;
setText(justifyText());
invalidate();
}
private float getWordWidth(String word) {
return getPaint().measureText(word);
}
@Override
protected void onDraw(Canvas canvas) {
if (!justify)
super.onDraw(canvas);
else
justify();
}
}
我非常感谢任何可以对此有所了解的人。
【问题讨论】:
-
解决了吗
-
是的,我自己解决了,并根据您提供的链接之一将其标记为已解决。当然是写在答案里了。
标签: android textview android-custom-view spannablestring