简体   繁体   English

如何在android TextView中获取点击跨度的x,y位置?

[英]How to get x,y position of clicked span in android TextView?

I have a spannable Textview.我有一个可跨越的 Textview。 I want to show popup window on top of selected span inside TextView .我想在TextView内的选定跨度顶部显示弹出窗口。 like this:像这样:

在此处输入图片说明

my code is:我的代码是:

String definition = textView.getText().toString().trim();
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(definition, TextView.BufferType.SPANNABLE);

Spannable spans = (Spannable) textView.getText();
Integer[] indices = getIndices(
  textView.getText().toString(), ' ');
int start = 0;
int end = 0;

for (int i = 0; i <= indices.length; i++) {
  ClickableSpan clickSpan = getClickableSpan();
  end = (i < indices.length ? indices[i] : spans.length());
  spans.setSpan(clickSpan, start, end,
    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  start = end + 1;
  }

private Integer[] getIndices(String s, char c) {
int           pos     = s.indexOf(c, 0);
List<Integer> indices = new ArrayList<Integer>();
while (pos != -1) {
  indices.add(pos);
  pos = s.indexOf(c, pos + 1);
}
return (Integer[]) indices.toArray(new Integer[0]);
}

private ClickableSpan getClickableSpan() {
return new ClickableSpan() {
  @SuppressLint("ClickableViewAccessibility")
  @Override
  public void onClick(View widget) {
    TextView tv = (TextView) widget;
    final String word = tv
            .getText()
            .subSequence(tv.getSelectionStart(),
                    tv.getSelectionEnd()).toString();

    tv.setOnTouchListener(new OnTouchListener() {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
        popup(word, (int) event.getRawX(), (int) event.getRawY());
        return false;
      }
    });

  }

};
}

as you see in image code working but because of onTouch called before onClick in android, popup showing word that clicked in prior step.正如您在图像代码中看到的那样,但由于在 android 中的onClick之前调用了onTouch ,弹出窗口显示了在上一步中单击的单词。 sorry for may bad English.抱歉可能英语不好。

        val parentTextViewRect = Rect()
        val textViewLayout = parentTextView.layout
        val startXCoordinatesOfClickedText = textViewLayout.getPrimaryHorizontal(spanStart).toDouble()
        val endXCoordinatesOfClickedText = textViewLayout.getPrimaryHorizontal(spanEnd).toDouble()

        val currentLineStartOffset = textViewLayout.getLineForOffset(spanStart)
        val currentLineEndOffset = textViewLayout.getLineForOffset(spanEnd)

        // 文本是否跨行
        val keywordIsInMultiLine = currentLineStartOffset != currentLineEndOffset
        textViewLayout.getLineBounds(currentLineStartOffset, parentTextViewRect)

        // 屏幕中的真实位置
        val parentTopAndBottomOffset = parentTextView.top + parentTextView.paddingTop
        parentTextViewRect.top += parentTopAndBottomOffset
        parentTextViewRect.bottom += parentTopAndBottomOffset

        val parentLeftOffset = parentTextView.left + parentTextView.paddingLeft
        parentTextViewRect.left += (parentLeftOffset + startXCoordinatesOfClickedText).toInt()
        parentTextViewRect.right = (parentTextViewRect.left + endXCoordinatesOfClickedText - startXCoordinatesOfClickedText).toInt()

        var spanTextLeft = if (keywordIsInMultiLine) {
            parentTextViewRect.left
        } else {
            (parentTextViewRect.left + parentTextViewRect.right) / 2
        }
        val spanTextTop = parentTextViewRect.top
        Log.d("MainActivity", "spanTextLeft = $spanTextLeft")
        Log.d("MainActivity", "spanTextTop = $spanTextTop")

To get x and y you can set OnTouchListener to register click event要获得xy您可以设置OnTouchListener来注册点击事件

In Java在 Java 中

private void setOnTouchListener() {
    textView.setOnTouchListener((view, event) -> {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            float clickedX = event.getX();
            float clickedY = event.getY();
        }

        return false;
    });
}

In Kotlin在科特林

private fun setOnTouchListener() {
    text_view.setOnTouchListener { view, event ->
        if (event?.action == MotionEvent.ACTION_DOWN) {
            val clickedX = event.x
            val clickedY = event.y
        }

        false
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM