Android中使用SpannableStringBuilder实现单TextView多ClickSpan点击失效问题求助
问题排查&修复方案
存在的问题
- 错误配置LinkMovementMethod:你当前将
LinkMovementMethod.getInstance()设置给了复选框控件cbTermsOfService,但实际承载可点击Spannable文本的是termAndCondtionLabel,ClickableSpan响应点击必须依赖目标TextView设置LinkMovementMethod。 - 重复赋值覆盖有效配置:你先构建了包含正确点击Span的
spannableString并赋值给TextView,后面又用buildSpannedString构建了错误的富文本重新赋值,直接覆盖了前面的有效配置。 - buildSpannedString使用错误:在第一个
inSpans代码块中,你只在闭包内创建了ClickableSpan实例,没有将其传入inSpans的参数列表,该Span不会被绑定到文本上。 - TextView拦截点击事件:布局中
termAndCondtionLabel设置了android:clickable="true",会优先消费点击事件,导致Span的点击无法触发。
修复步骤
- 先修改布局,删除
termAndCondtionLabel的android:clickable="true"属性 - 调整业务代码,去掉给复选框设置
movementMethod的逻辑,删除重复的buildSpannedString赋值代码,给承载文本的TextView配置正确的movementMethod
修复后代码
// 复选框点击逻辑保留即可 binding.bottomButtonLayout.cbTermsOfService.setOnClickListener { it.isChecked = !it.isChecked binding.bottomButtonLayout.btnGetstartedSmsm.isEnabled = it.isChecked } private fun updateTermsAndCondition(){ val completeText = "I hereby accept that I have read and agree to the Terms and Conditions and Key Fact Statement" val termsTextToFind = "Terms and Conditions" val keyFactTextToFind = "Key Fact Statement" val spannableString = SpannableString(completeText) val startFocusTerms = completeText.indexOf(termsTextToFind) val endFocusTerms = startFocusTerms + termsTextToFind.length val startFocusKey = completeText.indexOf(keyFactTextToFind) val endFocusKey = startFocusKey + keyFactTextToFind.length // 设置Terms and Conditions点击、样式 spannableString.setSpan(object: ClickableSpan() { override fun onClick(view: View) { showTermsAndConditions() } // 不需要下划线可加这段重写逻辑 override fun updateDrawState(ds: TextPaint) { super.updateDrawState(ds) ds.isUnderlineText = false } }, startFocusTerms, endFocusTerms, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) spannableString.setSpan(StyleSpan(Typeface.BOLD), startFocusTerms, endFocusTerms, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) spannableString.setSpan(ForegroundColorSpan(ContextCompat.getColor(binding.termAndCondtionLabel.context,R.color.red_daily_limit)), startFocusTerms, endFocusTerms, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) // 设置Key Fact Statement点击、样式 spannableString.setSpan(object: ClickableSpan() { override fun onClick(view: View) { showKeys() } // 不需要下划线可加这段重写逻辑 override fun updateDrawState(ds: TextPaint) { super.updateDrawState(ds) ds.isUnderlineText = false } }, startFocusKey, endFocusKey, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) spannableString.setSpan(StyleSpan(Typeface.BOLD), startFocusKey, endFocusKey, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) spannableString.setSpan(ForegroundColorSpan(ContextCompat.getColor(binding.termAndCondtionLabel.context,R.color.red_daily_limit)), startFocusKey, endFocusKey, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) // 给承载文本的TextView设置LinkMovementMethod,必须加 binding.termAndCondtionLabel.movementMethod = LinkMovementMethod.getInstance() // 赋值富文本 binding.termAndCondtionLabel.text = spannableString }
内容的提问来源于stack exchange,提问作者Atif AbbAsi
相关产品推荐
相关产品推荐

