2012-08-10 36 views
12

私は多くのClickableSpanを持つTextViewを持っています。TextView内のClickableSpanの座標を取得する方法は?

ClickableSpanをクリックすると、彼の位置にカスタムViewを表示するために、その画面上の座標を取得する必要があります。

問題は、どのように私がこれを行うことができるのか分かりません。 ClickableSpanonClick()メソッドは、ClickableSpanを含むViewTextViewというパラメータを与えます。

私は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 
); 
関連する問題