2012-07-22 52 views
19

基本上,我想顯示一段文字(可能是很長的文本),並允許用戶單擊任何單詞。那時,我想確定他們點擊了哪個單詞。我也想要得到整個單詞出現的句子(假設我可以確定單詞在文本中的位置),這很簡單。確定在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(); 
    } 
} 

如果有人有更好的主意,我很樂意聽到它。

在此先感謝, 戴夫

不知道如何我真的要回答計算器的問題,但我已經成功地擷取了一些代碼出了Android API 15,並修改它略微做我需要什麼。感謝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); 
} 

回答

10

如果您要將API級別設置爲14+,則可以使用getOffsetForPosition()

對於以前的Android版本,請查看您是否可以從Android源代碼複製此方法的代碼並擴展您自己的TextView。

+0

聽起來很有希望。我預先API 14,但希望應該能夠從代碼中獲得它。謝謝Dheeraj – 2012-07-22 18:02:03

+2

再次感謝Dheeraj。我把代碼撕掉了,它工作得很好。 – 2012-07-22 18:21:03