- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
因此,正如你们大多数人所知,在 Android 的 TextView 中没有文本对齐。所以,我构建了一个自定义 TextView 来解决这个问题。但是,出于某种原因,有时标点符号会在某些设备中由于某种原因而中断行。我在 LG G3 和模拟器(运行最新版本的 Nexus 4)和逗号“,”上进行了测试,例如打破了 LG G3 上的理由,但在模拟器上没有。
如果我添加一个至少为 2 的 Padding start 和 end(或 left 和 right),问题就解决了。这对我来说看起来很武断。
基本上,我的逻辑是为了证明文本的合理性,我需要知道 TextView 本身的宽度,将文本构造成最大长度的行。然后,通过找到行中的空格数和剩余的空白空间,根据剩余像素(或 View 中的空间)拉伸(stretch)要缩放的“”(空格)字符。
它几乎完美地工作,而且大多数时候它也支持 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();
}
}
我将非常感谢任何可以阐明这一点的人。
最佳答案
所以,在仔细研究之后:https://github.com/ufo22940268/android-justifiedtextview和一般的 TextView,我发现我的主要问题是我的方法。
使用缩放“”字符宽度的方法在理论上是合理的,但这样做之后,线条的宽度再次发生变化,因为线条的宽度似乎不是其各部分的总和。
我改变了我的方法并从上面的链接中获得灵感,所以在我的新方法中我单独绘制每个字符,而不是绘制整条线。如果文本需要对齐(基于自定义的“justify” bool 属性),那么它会画线并对齐它,否则它只会画线。
编辑:我现在更改了代码,以便它也支持 RTL 文本。我将在接下来的几天内将代码上传到某个地方。
代码如下:
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 提供的链接
关于android - 在 Android 的 TextView 中对齐文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44368339/
表架构 DROP TABLE bla; CREATE TABLE bla (id INTEGER, city INTEGER, year_ INTEGER, month_ INTEGER, val I
我需要拆分字符串/或从具有以下结构的字符串中获取更容易的子字符串。 字符串将来自 window.location.pathname 或 window.location.href,看起来像 text/n
每当将对象添加到数组中时,我都会尝试更新 TextView ,并在 TextView 中显示该文本,如下所示: "object 1" "object 2" 问题是,每次将新对象添加到数组时,它都会覆盖
我目前正在寻找使用 Java 读取网站可见文本并将其存储为纯文本字符串的方法。 换句话说,我想转换成这样: Hello stupid World进入“ Hello World ” 或者类似的东西 Un
我正在尝试以文本和 HTML 格式发送电子邮件,但无法正确发送正确的 header 。特别是,我想设置 Content-Type header ,但我找不到如何为 html 和文本部分单独设置它。 这
我尝试了上面的代码,但我无法绑定(bind)文本,我怎样才能将资源内部文本 bloc
我刚刚完成了 Space Shooter 教程,由于没有 GUIText 对象,所以我创建了 UI.Text 对象并进行了相应的编码。它在统一播放器中有效,但在构建 Web 应用程序后无效。我花了一段
我有这个代码: - (IBAction)setButtonPressed:(id)sender { NSUserDefaults *sharedDefaults = [[NSUserDefau
抱歉标题含糊不清,但我想不出我想在标题中做什么。无论如何,对于图像上的文本,我使用了 JLabel 文本并将其添加到图标中。 JLabel icon = new JLabel(new Imag
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我在将 Twitter 嵌入到我从 HTML 5 转换的 wordpress 运行网站时遇到问题。 我遇到的问题是推文不是我的自定义字体... 这是我无法使用任何 css 定位的 HTML 代码,我正
我正在尝试找到解决由于使用以下形式的代码而导致的冗余字符串连接问题的最佳方法: logger.debug("Entering loop, arg is: " + arg) // @1 在大多数情况下,
我写了这个测试 @Test public void removeRequestTextFromRouteError() throws Exception { String input = "F
我目前正在创建一个正则表达式来拆分所有匹配以下格式的字符串:&[文本],并且需要获取文本。字符串可能类似于:something &[text] &[text] everything &[text] 等
有没有办法将标题文本从一个词变形为另一个词,同时保留两个词中使用的字母?我看过的许多 css 文本动画大多是视觉的,很少有旋转整个单词的。 我想要做的是从一个词过渡,例如“BEACH”到“CHANGE
总结matplotlib绘图如何设置坐标轴刻度大小和刻度。 上代码: ?
我在容器 (1) 中创建了容器 (2)。你能帮忙如何向容器(1)添加文本吗?下面是我的代码 return Scaffold( body: Padding( padding: c
我似乎找不到任何人或任何人这样做过。我试图限制我们使用的图像数量,并想创建一个带有渐变作为其“颜色”的文本,并在其周围设置渐变轮廓/描边 到目前为止,我还没有看到任何将两者结合在一起的东西。 我可以自
我正在为视频游戏暗黑破坏神 2 使用 discord.py 构建一个不和谐机器人。其中一项功能要求机器人从暗黑破坏神 2 屏幕截图中提取项目的名称和属性。我目前正在为此使用 pytesseract,但
我很难弄清楚如何旋转 strip.text theme 中的属性来自 ggplot2 .我使用的是 R 版本 3.4.2 和 ggplot2 版本 2.2.1。 以下是 MWE 的数据。 > dput
我是一名优秀的程序员,十分优秀!