android textview 点选单词,确定在android textview中单击了哪个单词

基本上,我想显示一段文本(可能是相当长的文本),并允许用户点击任何单词。 那时,我想确定他们点击了哪个单词。 我还想得到单词出现的整个句子(这是非常简单的,假设我可以确定单词在文本中的位置)。

理想情况下,我只是听一个onTouch事件,得到X和Y,并说一些像textView.wordAt(event.x, event.y)或textView.cursorPositionNearest(event.x, event.y) ,但似乎这不容易:-)

我目前的最大努力是使用TextView并为每个单词创建一个ClickableSpan 。 它可以工作,但它不是很优雅,我想如果我在较长的文本上使用它会开始吃内存。

private final String text = "This is the text"; private TextView textView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_text_view); textView = (TextView) findViewById(R.id.text_view); SpannableString ss = new SpannableString(text); // create spans for "this", "is", "the" and "text" ss.setSpan(new IndexedClickableSpan(0, 4), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); ss.setSpan(new IndexedClickableSpan(5, 7), 5, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); ss.setSpan(new IndexedClickableSpan(8, 11), 8, 11, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); ss.setSpan(new IndexedClickableSpan(12, 16), 12, 16, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); textView.setText(ss); } private final class IndexedClickableSpan extends ClickableSpan { int startIndex, endIndex; public IndexedClickableSpan(int startIndex, int endIndex) { this.startIndex = startIndex; this.endIndex = endIndex; } @Override public void onClick(View widget) { String word = TextViewActivity.this.text.substring(startIndex, endIndex); Toast.makeText(TextViewActivity.this, "You clicked on " + word, Toast.LENGTH_SHORT).show(); } }

如果有人有更好的主意,我很乐意听到。

提前谢谢,戴夫

我不确定我是如何回答有关stackoverflow的问题,但我已经设法从Android 15 API中删除一些代码并稍微修改它以完成我需要的操作。 感谢Dheeraj提出的建议。

新代码允许我根据触摸事件位置获得插入位置,从那里我应该能够获得被触摸的单词以及它出现的句子。附加代码:

public int getOffsetForPosition(TextView textView, float x, float y) { if (textView.getLayout() == null) { return -1; } final int line = getLineAtCoordinate(textView, y); final int offset = getOffsetAtCoordinate(textView, line, x); return offset; } private int getOffsetAtCoordinate(TextView textView2, int line, float x) { x = convertToLocalHorizontalCoordinate(textView2, x); return textView2.getLayout().getOffsetForHorizontal(line, x); } private float convertToLocalHorizontalCoordinate(TextView textView2, float x) { x -= textView2.getTotalPaddingLeft(); // Clamp the position to inside of the view. x = Math.max(0.0f, x); x = Math.min(textView2.getWidth() - textView2.getTotalPaddingRight() - 1, x); x += textView2.getScrollX(); return x; } private int getLineAtCoordinate(TextView textView2, float y) { y -= textView2.getTotalPaddingTop(); // Clamp the position to inside of the view. y = Math.max(0.0f, y); y = Math.min(textView2.getHeight() - textView2.getTotalPaddingBottom() - 1, y); y += textView2.getScrollY(); return textView2.getLayout().getLineForVertical((int) y); }

如果您的目标是API级别14+,则可以使用getOffsetForPosition() 。

对于以前的Android版本,请查看是否可以从Android源复制此方法的代码并扩展自己的TextView。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值