一 、需求分析
如下图:登陆界面有一个文字说明,其中 Service Terms 和 Privacy Policy 两个词需要高亮显示,且要求点击之后进入相应的页面。
首先我想到的是对Service Terms 和 Privacy Policy 使用不同的TextView,但是这样布局非常麻烦,且需要使用多个TextView,而且对于不同分辨率的手机可能无法完美适配。那么,如果使用一个TextView能不能实现需求呢,我已经知道TextView可以支持改变指定字符的颜色,那么能不能支持给指定字符添加点击事件呢? 在网上查了一下,还真能。
二、 关键代码
那么就简单粗暴地直接上代码好了。
private void setServicePolicy(){
String itemStr = tvLoginPolicy.getText().toString();
String serviceStr = "Service Terms";
String policyStr = "Privacy Policy";
int indexService = itemStr.indexOf(serviceStr);
int indexPolicy = itemStr.indexOf(policyStr);
SpannableString spannableString = new SpannableString(itemStr);
//Service Terms 颜色和点击事件
spannableString.setSpan(new ClickableSpan() {
@Override
public void onClick(View view) {
LogDebugUtil.e(TAG, "clicked Service Terms");
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setColor(Color.BLACK);
ds.setUnderlineText(true);
}
}, indexService, indexService + serviceStr.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//Privacy Policy 颜色和点击事件
spannableString.setSpan(new ClickableSpan() {
@Override
public void onClick(View view) {
LogDebugUtil.e(TAG, "clicked Privacy Policy");
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setColor(Color.BLACK);
ds.setUnderlineText(true);
}
}, indexPolicy, indexPolicy + policyStr.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tvLoginPolicy.setText(spannableString);
tvLoginPolicy.setMovementMethod(LinkMovementMethod.getInstance());
}
- 这段代码字符串直接写在了代码里,但不建议这样写,指定字符串最好放在资源文件里再通过代码获取,这里只是为了展示。
- 在 updateDrawState 方法里可以设置字符的颜色,以及是否需要下划线。对于可点击字符,最好加上下划线,不然用户可能不知道哪里可以点击。
- 最后一句代码 tvLoginPolicy.setMovementMethod(LinkMovementMethod.getInstance()) 必须添加,不然字符无法响应点击事件。