Android ClickableSpan not calling onClick

2019-01-16 08:46发布

I am creating a ClickableSpan, and it is displaying properly with the proper text underlined. However the clicks are not registering. Do you know what I am doing wrong??? Thanks, Victor Here is the code snippet:

view.setText("This is a test");       
ClickableSpan span = new ClickableSpan() {
    @Override
    public void onClick(View widget) { 
        log("Clicked"); 
    }
}; 
view.getText().setSpan(span, 0, view.getText().length(),
                       Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

3条回答
三岁会撩人
2楼-- · 2019-01-16 09:15

Kotlin util function:

fun setClickable(textView: TextView, subString: String, handler: () -> Unit, drawUnderline: Boolean = false) {
    val text = textView.text
    val start = text.indexOf(subString)
    val end = start + subString.length

    val span = SpannableString(text)
    span.setSpan(ClickHandler(handler, drawUnderline), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)

    textView.linksClickable = true
    textView.isClickable = true
    textView.movementMethod = LinkMovementMethod.getInstance()

    textView.text = span
}

class ClickHandler(
        private val handler: () -> Unit,
        private val drawUnderline: Boolean
) : ClickableSpan() {
    override fun onClick(widget: View?) {
        handler()
    }

    override fun updateDrawState(ds: TextPaint?) {
        if (drawUnderline) {
            super.updateDrawState(ds)
        } else {
            ds?.isUnderlineText = false
        }
    }
}

Usage:

Utils.setClickable(textView, subString, {handleClick()})
查看更多
Juvenile、少年°
3楼-- · 2019-01-16 09:16

Have you tried setting the MovementMethod on the TextView that contains the span? You need to do that to make the clicking work...

tv.setMovementMethod(LinkMovementMethod.getInstance());
查看更多
SAY GOODBYE
4楼-- · 2019-01-16 09:25

After some trial and error, the sequence of setting the tv.setMovementMethod(LinkMovementMethod.getInstance()); does matter.

Here's my full code

String stringTerms = getString(R.string.sign_up_terms);
Spannable spannable = new SpannableString(stringTerms);
int indexTermsStart = stringTerms.indexOf("Terms");
int indexTermsEnd = indexTermsStart + 18;
spannable.setSpan(new UnderlineSpan(), indexTermsStart, indexTermsEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(new ForegroundColorSpan(getColor(R.color.theme)), indexTermsStart, indexTermsEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(new ClickableSpan() {
    @Override
    public void onClick(View widget) {
        Log.d(TAG, "TODO onClick.. Terms and Condition");
    }
}, indexTermsStart, indexTermsEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

int indexPolicyStart = stringTerms.indexOf("Privacy");
int indexPolicyEnd = indexPolicyStart + 14;
spannable.setSpan(new UnderlineSpan(), indexPolicyStart, indexPolicyEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(new ForegroundColorSpan(getColor(R.color.theme)), indexPolicyStart, indexPolicyEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(new ClickableSpan() {
    @Override
    public void onClick(View widget) {
        Log.d(TAG, "TODO onClick.. Privacy Policy");
    }
}, indexPolicyStart, indexPolicyEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

TextView textViewTerms = (TextView) findViewById(R.id.sign_up_terms_text);
textViewTerms.setText(spannable);
textViewTerms.setClickable(true);
textViewTerms.setMovementMethod(LinkMovementMethod.getInstance());
查看更多
登录 后发表回答