Android-clickableSpan和TextView问题

时间:2018-11-24 14:26:59

标签: android

我正在尝试在TextView中实现可点击的标签,如下所示:

mTextView.setMovementMethod(LinkMovementMethod.getInstance());

Spannable s = (Spannable) mTextView.getText();
CharacterStyle clickableSpan = new MyClickableSpan();
s.setSpan(clickableSpan, startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

这可以根据需要处理onClick的主题标签,但似乎文本的另一部分也侦听onClick事件,什么也不做。

我的问题是如何制作不可扩展的文本部分,将onClick事件委托给父视图,如下图所示。

enter image description here

3 个答案:

答案 0 :(得分:0)

您可以使用类似这样的内容:

`SpannableString string = new SpannableString(getString(R.string.some_string));
 ClickableSpan clickableSpan = new ClickableSpan() {
            @Override
            public void onClick(View textView) {
                //do something
            }`

            @Override
            public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);
                ds.setUnderlineText(false);
            }
        };

`string.setSpan(clickableSpan, string.length() - 20, string.length(),
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        textView.setText(string);
        textView.setMovementMethod(LinkMovementMethod.getInstance());`

答案 1 :(得分:0)

我在Kotlin使用下一个扩展程序

fun SpannableString.withClickableSpan(
    context: Context,
    clickablePart: String,
    onClickListener: () -> Unit
): SpannableString {
    val clickableSpan = object : ClickableSpan() {
        override fun onClick(widget: View?) {
            onClickListener.invoke()
        }
    }
    val clickablePartStart = indexOf(clickablePart)

    this.setSpan(
        clickableSpan,
        clickablePartStart, clickablePartStart + clickablePart.length,
        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
    )
    this.setSpan(
        ForegroundColorSpan(ContextCompat.getColor(context, R.color.cyan)),
        clickablePartStart, clickablePartStart + clickablePart.length,
        Spanned.SPAN_INCLUSIVE_EXCLUSIVE
    )

    return this
}

并这样称呼:

val span = SpannableString(text).withClickableSpan(requireContext(), text) {
   onRevisionDateClicked(view)
}
view.movementMethod = LinkMovementMethod.getInstance()
view.setText(span, TextView.BufferType.SPANNABLE)
view.isClickable = true

或者您可以在Java中使用类似的内容:

SpannableString ss = new SpannableString("Hello World");
ClickableSpan spanText = new ClickableSpan() {
   @Override
   public void onClick(View textView) {
      // do some thing
   }
};

ss.setSpan(spanText, 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

textView.setText(ss);
textView.setMovementMethod(LinkMovementMethod.getInstance());

答案 2 :(得分:0)

我想出了与此解决方案有关的问题,但是如果有人有更好的解决方案,请告诉我。

我为TextView设置了OnClickListener,在onClick事件中,我获取了TextView的父级,并检查父级是否可点击,然后执行父级onClick事件;如果不是,则递归获取父级的父级,直到获得可点击的父级。这样,标签标签仍可通过自己的操作单击,并且在单击文本的另一部分时,将执行父标签的onClick事件。

这是我递归地找到可点击的父代的代码:

private View getParentClickable(View view) {
    try {
        if (((View) view.getParent()).isClickable()) {
            return (View) view.getParent();
        } else {
            return getParentClickable(((View) view.getParent()));
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

,然后设置我的视图的onOnClickListener:

mTextView.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
       View parent = getParentClickable(mTextView);
       if (parent != null) parent.performClick();
   }
});