2012-08-10 1 views
12

У меня есть TextView со многими ClickableSpan.Как получить координату ClickableSpan внутри TextView?

Нажав на ClickableSpan, я должен получить координату на экране (показать пользовательский View в его положении).

Проблема в том, что я понятия не имею, как я могу это сделать. Метод onClick()ClickableSpan дает мне параметр a View, TextView, который содержит ClickableSpan.

Я использовал следующее, чтобы получить положение символов в TextView, но я не знаю, как я могу преобразовать его, чтобы получить положение x/y на экране текста.

@Override 
public void onClick(View v){ 

    SpannableString completeText = (SpannableString)((TextView) v).getText(); 
    Log.v("characters position", completeText.getSpanStart(this) + "/" + completeText.getSpanEnd(this)); 

} 

Заранее благодарим за вашу помощь!

EDIT: Я хочу получить всю координату ClickableSpan и ее размер, цель состоит в том, чтобы показать мой пользовательский вид в нижней части текста. Метод onTouch даст мне положение пальца, а не все текстовые координаты. Таким образом, с помощью этого метода у меня не будет середины текста.

+0

Переопределить onTouch() и использовать event.getX(), event.getY()? –

+1

Спасибо за ваш ответ! К сожалению, я нашел этот метод очень ... уродливым! Надеюсь, что есть лучшее решение. Более того, я забыл дать еще одну точность: я хочу получить всю координату ClickableSpan и ее размер, цель состоит в том, чтобы показать мой пользовательский вид в нижней части текста. Метод onTouch даст мне положение пальца, а не все текстовые координаты. Таким образом, с помощью этого метода у меня не будет середины текста. Любая другая идея? –

ответ

25

Я нашел решение :-) Вот оно, возможно, это поможет другим людям с той же проблемой, чем я!

// Initialize global value 
this.parentTextViewRect = new Rect(); 


// Initialize values for the computing of clickedText position 
SpannableString completeText = (SpannableString)(parentTextView).getText(); 
Layout textViewLayout = parentTextView.getLayout(); 

double startOffsetOfClickedText = completeText.getSpanStart(clickedText); 
double endOffsetOfClickedText = completeText.getSpanEnd(clickedText); 
double startXCoordinatesOfClickedText = textViewLayout.getPrimaryHorizontal((int)startOffsetOfClickedText); 
double endXCoordinatesOfClickedText = textViewLayout.getPrimaryHorizontal((int)endOffsetOfClickedText); 


// Get the rectangle of the clicked text 
int currentLineStartOffset = textViewLayout.getLineForOffset((int)startOffsetOfClickedText); 
int currentLineEndOffset = textViewLayout.getLineForOffset((int)endOffsetOfClickedText); 
boolean keywordIsInMultiLine = currentLineStartOffset != currentLineEndOffset; 
textViewLayout.getLineBounds(currentLineStartOffset, this.parentTextViewRect); 


// Update the rectangle position to his real position on screen 
int[] parentTextViewLocation = {0,0}; 
parentTextView.getLocationOnScreen(parentTextViewLocation); 

double parentTextViewTopAndBottomOffset = (
    parentTextViewLocation[1] - 
    parentTextView.getScrollY() + 
    this.parentTextView.getCompoundPaddingTop() 
); 
this.parentTextViewRect.top += parentTextViewTopAndBottomOffset; 
this.parentTextViewRect.bottom += parentTextViewTopAndBottomOffset; 

// In the case of multi line text, we have to choose what rectangle take 
if (keywordIsInMultiLine){ 

    int screenHeight = this.mWindowManager.getDefaultDisplay().getHeight(); 
    int dyTop = this.parentTextViewRect.top; 
    int dyBottom = screenHeight - this.parentTextViewRect.bottom; 
    boolean onTop = dyTop > dyBottom; 

    if (onTop){ 
     endXCoordinatesOfClickedText = textViewLayout.getLineRight(currentLineStartOffset); 
    } 
    else{ 
     this.parentTextViewRect = new Rect(); 
     textViewLayout.getLineBounds(currentLineEndOffset, this.parentTextViewRect); 
     this.parentTextViewRect.top += parentTextViewTopAndBottomOffset; 
     this.parentTextViewRect.bottom += parentTextViewTopAndBottomOffset; 
     startXCoordinatesOfClickedText = textViewLayout.getLineLeft(currentLineEndOffset); 
    } 

} 

this.parentTextViewRect.left += (
    parentTextViewLocation[0] + 
    startXCoordinatesOfClickedText + 
    this.parentTextView.getCompoundPaddingLeft() - 
    parentTextView.getScrollX() 
); 
this.parentTextViewRect.right = (int) (
    this.parentTextViewRect.left + 
    endXCoordinatesOfClickedText - 
    startXCoordinatesOfClickedText 
);