我有TextView
一个OnTouchListener
. 我想要的是当我得到MotionEvent
. 有什么办法可以得到底层的字体度量TextView
?
3 回答
你有没有尝试过这样的事情:
Layout layout = this.getLayout();
if (layout != null)
{
int line = layout.getLineForVertical(y);
int offset = layout.getOffsetForHorizontal(line, x);
// At this point, "offset" should be what you want - the character index
}
希望这可以帮助...
我不知道执行此操作的简单直接方法,但是您应该能够通过调用TextView.getPaint()使用 TextView 的Paint对象将某些东西放在一起
一旦你有了绘画对象,你就可以通过调用 Paint.getFontMetrics() 来访问底层的 FontMetrices,并可以访问其他函数,如 Paint.measureText() Paint.getTextBounds() 和 Paint.getTextWidths() 来访问显示文本的实际大小。
虽然它通常有效,但我对 Tony Blues 的回答有一些问题。
首先getOffsetForHorizontal返回一个偏移量,即使 x 坐标超出该行的最后一个字符。
其次,返回的字符偏移量有时属于下一个字符,而不是指针正下方的字符。显然,该方法返回最近光标位置的偏移量。这可能在角色的左侧或右侧,具体取决于附近的内容。
我的解决方案使用getPrimaryHorizontal来确定某个偏移量的光标位置,并使用二进制搜索来查找指针 x 坐标下方的偏移量。
public static int getCharacterOffset(TextView textView, int x, int y) {
x += textView.getScrollX() - textView.getTotalPaddingLeft();
y += textView.getScrollY() - textView.getTotalPaddingTop();
final Layout layout = textView.getLayout();
final int lineCount = layout.getLineCount();
if (lineCount == 0 || y < layout.getLineTop(0) || y >= layout.getLineBottom(lineCount - 1))
return -1;
final int line = layout.getLineForVertical(y);
if (x < layout.getLineLeft(line) || x >= layout.getLineRight(line))
return -1;
int start = layout.getLineStart(line);
int end = layout.getLineEnd(line);
while (end > start + 1) {
int middle = start + (end - start) / 2;
if (x >= layout.getPrimaryHorizontal(middle)) {
start = middle;
}
else {
end = middle;
}
}
return start;
}
编辑:这个更新的版本在不自然的换行符下效果更好,当一个长的单词不适合一行并且在中间的某个地方被分割时。
警告:在带连字符的文本中,单击行尾的连字符会返回其旁边字符的索引。此方法也不适用于 RTL 文本。