Spannable.SPAN_EXCLUSIVE_EXCLUSIVE设置SpannableString出错

本文探讨了在使用Spannable设置Span时遇到的一个奇怪错误:当使用SPAN_INCLUSIVE_EXCLUSIVE模式时,在EditText中删除Span后再输入字符,Span会重新出现。文章通过对比不同设置方式的效果,分析了此现象的原因。

一个非常奇怪的错误

 

spannable.setSpan(topicSpan,
                    topicMatcher.start(),
                    topicMatcher.end(),
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

 

设置成这样没什么问题

但是设置成

 Spannable.SPAN_INCLUSIVE_EXCLUSIVE

就会出现在EditText里面按删除键取消Span后,又输入一个字,Span又出来的情况

 

将下列代码转化为fragment:private lateinit var checkBox1: CheckBox private lateinit var checkBox2: CheckBox private lateinit var confirmButton: Button override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.login) // 按钮初始状态 checkBox1 = findViewById(R.id.checkbox1) checkBox2 = findViewById(R.id.checkbox2) val confirmButton = findViewById<Button>(R.id.btn_agree) confirmButton.setTextColor((Color.parseColor("#A7A9AC"))) //检查复选框状态并更新 val updateButtonState = { val bothChecked = checkBox1.isChecked && checkBox2.isChecked if (bothChecked) { confirmButton.isEnabled = true confirmButton.setTextColor(Color.parseColor("#1BCBFF")) } } checkBox1.setOnCheckedChangeListener { _, _ -> updateButtonState() } checkBox2.setOnCheckedChangeListener { _, _ -> updateButtonState() } // 点击事件 confirmButton.setOnClickListener { if (checkBox1.isChecked && checkBox2.isChecked) { Log.d("ConfirmButton", "发生点击") supportFragmentManager.beginTransaction() .replace(R.id.fragment_container, PassWordFragment()) .addToBackStack(null) .commit() } } // 设置文本内容可点击 val privacyText = findViewById<TextView>(R.id.PrivacyPolicy) val termsText = findViewById<TextView>(R.id.TermsofUse) // 设置Privacy Policy部分 val fullPrivacyText = "I have fully read and accepted the Privacy Policy and Terms of Use." val spannablePrivacy = SpannableString(fullPrivacyText) // 为"Privacy Policy"添加样式和点击事件 val privacyStart = fullPrivacyText.indexOf("Privacy Policy") val privacyEnd = privacyStart + "Privacy Policy".length spannablePrivacy.setSpan(StyleSpan(Typeface.NORMAL), privacyStart, privacyEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) spannablePrivacy.setSpan(UnderlineSpan(), privacyStart, privacyEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) spannablePrivacy.setSpan(object : ClickableSpan() { override fun onClick(widget: View) { // 跳转到Fragment1 supportFragmentManager.beginTransaction() .replace(R.id.fragment_container, PrivacyPolicyFragment()) .addToBackStack(null) .commit() } }, privacyStart, privacyEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) // 为"Terms of Use"添加样式和点击事件 val termsStart = fullPrivacyText.indexOf("Terms of Use") val termsEnd = termsStart + "Terms of Use".length spannablePrivacy.setSpan(StyleSpan(Typeface.NORMAL), termsStart, termsEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) spannablePrivacy.setSpan(UnderlineSpan(), termsStart, termsEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) spannablePrivacy.setSpan(object : ClickableSpan() { override fun onClick(widget: View) { // 跳转到Fragment2 supportFragmentManager.beginTransaction() .replace(R.id.fragment_container, TermsofUseFragment()) .addToBackStack(null) .commit() } }, termsStart, termsEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) privacyText.text = spannablePrivacy privacyText.movementMethod = LinkMovementMethod.getInstance() // 启用点击 // 设置User Experience部分 val ueText = "I agree to join the User Experience Improvement Program." val spannableUE = SpannableString(ueText) val ueStart = ueText.indexOf("User Experience Improvement Program") val ueEnd = ueStart + "User Experience Improvement Program".length spannableUE.setSpan(object : ClickableSpan() { override fun onClick(widget: View) { // 跳转到Fragment3 supportFragmentManager.beginTransaction() .replace(R.id.fragment_container, UserExperienceImprovProgramFragment()) .addToBackStack(null) .commit() } }, ueStart, ueEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) termsText.text = spannableUE termsText.movementMethod = LinkMovementMethod.getInstance() } }
08-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值