16

私はTextViewたくさんの を持っていClickableSpanます。

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

問題は、これを行う方法がわからないことです。のonClick()メソッドは、を含むClickableSpanパラメーター a で私に与えViewます。TextViewClickableSpan

以下を使用して文字の位置を取得しました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));

}

よろしくお願いします。

編集: ClickableSpan の座標全体とそのサイズを取得したいのですが、目的は、テキストの下部中央にカスタム ビューを表示することです。onTouch メソッドは、テキスト全体の座標ではなく、指の位置を教えてくれます。したがって、この方法では、テキストの途中にはなりません。

4

2 に答える 2

34

私は解決策を見つけました:-)ここにあります、これは私のような同じ問題を抱えている他の人を助けるかもしれません!

// 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
);
于 2012-08-13T12:33:59.073 に答える
0

これを試して:

CustomSpannableString クラスの onClick 関数内

@Override
public void onClick(View v){
    val textView = v as TextView
    val s = textView.text as Spanned
    val startCoordinates = s.getSpanStart(this)
    val endCoordinates = s.getSpanEnd(this)
    return  arrayOf(startCoordinates, endCoordinates)
}

spannableString クラスにない

val textView = findView...   // txtView which text is set to SpannableString
val s = textView.text as Spanned 
// CustomSpannableStringObj of type CustomSpannableString 
val startCoordinates = s.getSpanStart(CustomSpannableStringObj)
val endCoordinates = s.getSpanEnd(CustomSpannableStringObj)
于 2021-09-17T14:37:34.770 に答える