Подтвердить что ты не робот

Как получить координату ClickableSpan внутри TextView?

У меня есть TextView со многими ClickableSpan.

При нажатии на 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 даст мне положение пальца, а не все текстовые координаты. Таким образом, с помощью этого метода у меня не будет середины текста.

4b9b3361

Ответ 1

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

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

Ответ 2

У меня недостаточно репутации, чтобы комментировать, но мне просто интересно, что вы указали в качестве переменной clickedText для начального и конечного смещения?