项目中要实现一个这样的效果,不想画太多的布局,突然想到用SpannableString来实现这种效果。
之前没在项目中用过这东西。结果使用中出现了个大坑。
SpannableString 的用法大家应该都知道。我们通常使用SpannableString.setSpan(); 来给它设置一些属性。然而这个setSpan();很坑。
因为一个SpannableString 同时调用两次setSpan() 来设置字体区间颜色只能显示最后一次为区间设置的颜色
SpannableString span = new SpannableString("哇,您还有 " + num + " 次抽奖机会!" + "点击抽奖"); ForegroundColorSpan colorSpan = new ForegroundColorSpan(Color.parseColor("#07FCF5")); span.setSpan(colorSpan,6, 6 + num.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); span.setSpan(colorSpan,span.length() - 4, span.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); tvCoffersMsg.setText(span);
这样设置的话只有 点击抽奖 四个字是我们设置的颜色。
那么怎么样才能显示图片上文字的效果呢。
SpannableString span = new SpannableString("哇,您还有 " + num + " 次抽奖机会!" + "点击抽奖"); span.setSpan(new ForegroundColorSpan(Color.parseColor("#07FCF5")), 6, 6 + num.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); span.setSpan(new ForegroundColorSpan(Color.parseColor("#07FCF5")),span.length() - 4, span.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
这样可以实现文字的效果,但是我们还有一个点击事件,加上点击事件后, 点击抽奖四个字没有了。。
span.setSpan(new ClickableSpan() { @Override public void onClick(View widget) { } }, span.length() - 4, span.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tvCoffersMsg.setMovementMethod(LinkMovementMethod.getInstance());
那么怎么样才能既有文字颜色效果,又能点击事件呢?就是同时设置ClickableSpan 和 ForegroundColorSpan 颜色和点击效果同时实现。可以使用UnderlineSpan,并重写updateDrawState方法,就解决了我们的问题。
SpannableString span = new SpannableString("哇,您还有 " + num + " 次抽奖机会!" + "点击抽奖"); span.setSpan(new ForegroundColorSpan(Color.parseColor("#07FCF5")), 6, 6 + num.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); span.setSpan(new ClickableSpan() { @Override public void onClick(View widget) { } }, span.length() - 4, span.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); span.setSpan(new UnderlineSpan() { @Override public void updateDrawState(TextPaint ds) { super.updateDrawState(ds); ds.setColor(Color.parseColor("#07FCF5")); ds.setUnderlineText(false);// 去掉下划线 } }, span.length() - 4, span.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); tvCoffersMsg.setText(span); tvCoffersMsg.setMovementMethod(LinkMovementMethod.getInstance());以后设置一句话多种不同文字颜色时,其实就可以使用 UnderlineSpan 它不会造成ForegroundColorSpan 产生的问题。并且可以设置多次。