Android 通过 SpannableStringBuilder 实现登录页各种超链接的效果
- 原始字符串;
<string name="user_protocol">新用户登录即完成注册,代表同意《用户协议》、《隐私协议》以及《法律声明》。</string>
- 要求只有三个协议染色,并可点击跳转到指定页面;
- 具体代码实现;
val spannableStringBuilder = SpannableStringBuilder()
spannableStringBuilder.append(string(R.string.user_protocol))
// 用户协议
val userProtocolClickSpan = object : ClickableSpan() {
override fun onClick(widget: View) {
// 跳转指定页
}
override fun updateDrawState(ds: TextPaint) {
ds.isUnderlineText = false // 去除下划线
}
}
val startUserProtocol = spannableStringBuilder.indexOf("《隐私协议》")
val endUserProtocol = startUserProtocol + "《用户协议》".length
spannableStringBuilder.setSpan(userProtocolClickSpan, startUserProtocol, endUserProtocol, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
spannableStringBuilder.setSpan(ForegroundColorSpan(color(R.color.color_blue_theme)), startUserProtocol, endUserProtocol, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) // 设置协议字体颜色
// 隐私协议
val privacyProtocolClickSpan = object : ClickableSpan() {
override fun onClick(widget: View) {
// 跳转指定页
}
override fun updateDrawState(ds: TextPaint) {
ds.isUnderlineText = false // 去除下划线
ds.color = color(R.color.color_blue_theme) // 设置字体颜色
}
}
val startPrivacyProtocol = spannableStringBuilder.indexOf("《隐私协议》")
val endPrivacyProtocol = startPrivacyProtocol + "《隐私协议》".length
spannableStringBuilder.setSpan(privacyProtocolClickSpan, startPrivacyProtocol, endPrivacyProtocol, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
// 法律声明
val legalStatementClickSpan = object : ClickableSpan() {
override fun onClick(widget: View) {
// 跳转指定页
}
override fun updateDrawState(ds: TextPaint) {
ds.isUnderlineText = false // 去除下划线
ds.color = color(R.color.color_blue_theme) // 设置字体颜色
}
}
val startLegalStatement = spannableStringBuilder.indexOf("《法律声明》")
val endLegalStatement = startLegalStatement + "《法律声明》".length
spannableStringBuilder.setSpan(legalStatementClickSpan, startLegalStatement, endLegalStatement, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
tv_protocol.movementMethod = LinkMovementMethod.getInstance()
tv_protocol.text = spannableStringBuilder
注意:
#16
和#25
/#39
的效果一样;#16
可以更换大段内容的颜色,不需要逐个去设置;#16
方式下,ForegroundColorSpan(color(R.color.color_blue_theme)
需要每次都创建一个新的对象,不可多处使用同一个对象,否则前面设置不会生效,只有最后一次设置的才有效果;
网友评论