Về cơ bản, tôi muốn hiển thị một đoạn văn bản (có khả năng, văn bản khá dài) và cho phép người dùng nhấp vào bất kỳ từ nào. Tại thời điểm đó, tôi muốn xác định từ nào họ đã nhấp vào. Tôi cũng muốn nhận được toàn bộ câu mà từ đó xuất hiện (điều này là khá tầm thường, giả sử tôi có thể xác định vị trí của từ trong văn bản).Xác định từ nào được nhấp trong văn bản android
Lý tưởng nhất, tôi sẽ chỉ lắng nghe một sự kiện onTouch, có X và Y, và nói điều gì đó như textView.wordAt(event.x, event.y)
hoặc textView.cursorPositionNearest(event.x, event.y)
, nhưng có vẻ như nó không phải là dễ dàng như vậy :-)
nỗ lực tối đa hiện tại của tôi liên quan đến việc sử dụng một TextView và tạo một ClickableSpan mỗi từ. Nó hoạt động, nhưng nó không phải là chính xác tao nhã, và tôi đoán nó sẽ bắt đầu ăn bộ nhớ nếu tôi sử dụng nó trên văn bản dài hơn.
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();
}
}
Nếu có ý tưởng hay hơn, tôi rất muốn nghe.
Cảm ơn trước, Dave
Không chắc thế nào tôi đang thực sự phải trả lời câu hỏi trên stackoverflow, nhưng tôi đã quản lý để rip một số mã ra khỏi Android 15 API và sửa đổi nó rất nhẹ để làm những gì tôi cần. Cảm ơn Dheeraj đã đề xuất.
Các mã mới cho phép tôi để có được một vị trí dấu nháy dựa trên một vị trí sự kiện liên lạc, từ đó tôi sẽ có thể có được chữ đó rất cảm động, và câu nó xuất hiện trong Bộ luật kèm theo:.
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);
}
Âm thanh đầy hứa hẹn. Tôi đang sử dụng API 14, nhưng hy vọng sẽ có thể lấy nó từ mã. Cảm ơn Dheeraj –
Cảm ơn một lần nữa Dheeraj. Tôi tách mã ra và nó hoạt động rất độc đáo. –