2012-08-10 12 views
12

Ho un TextView con molti ClickableSpan.Come ottenere coordinate di ClickableSpan all'interno di TextView?

Al clic su un ClickableSpan, devo ottenere la coordinata sullo schermo di esso (per mostrare un custom View nella sua posizione).

Il problema è che non ho idea di come posso farlo. Il metodo onClick() di ClickableSpan mi fornisce nel parametro a View, il TextView che contiene ClickableSpan.

Ho usato quanto segue per ottenere la posizione dei caratteri nel TextView, ma non so come posso convertirlo per ottenere la posizione x/y sullo schermo del testo.

@Override 
public void onClick(View v){ 

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

} 

Grazie in anticipo per il vostro aiuto!

MODIFICA: Voglio ottenere l'intera coordinata di ClickableSpan e le sue dimensioni, l'obiettivo è mostrare la mia vista personalizzata in basso al centro del testo. Il metodo onTouch mi darà la posizione del dito, non le coordinate del testo intero. Quindi, con questo metodo, non avrò la parte centrale del testo.

+0

Sostituire onTouch() e utilizzare event.getX(), event.getY()? –

+1

Grazie per la tua risposta! Purtroppo, ho trovato questo metodo molto ... brutto! Spero che ci sia una soluzione migliore. Inoltre, ho dimenticato di dare un'altra precisazione: voglio ottenere l'intera coordinata di ClickableSpan e le sue dimensioni, l'obiettivo è mostrare la mia vista personalizzata in basso al centro del testo. Il metodo onTouch mi darà la posizione del dito, non le coordinate del testo intero. Quindi, con questo metodo, non avrò la parte centrale del testo. Qualche altra idea? –

risposta

25

Ho trovato una soluzione :-) Eccolo, potrebbe essere questo aiuterà altre persone con lo stesso problema di me!

// 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 
); 
Problemi correlati