使用Span实现各种酷炫效果
来源:互联网 发布:动画片制作软件 编辑:程序博客网 时间:2024/05/21 20:40
前一段时间一直在做富文本展示和文本处理,主要用到了Html.fromHtml()实现加载网页,但实现整段文本的某些特殊如个别文字的点击,改背景色、前景色等效果,就用到了我们今天要用到的Span这个类。
关于加载网页或个别文字点击效果,可以阅读我之前写的一篇文章——用TextView实现富文本展示,点击断句和语音播报。
您也关注:
- https://github.com/shuaijia/SpanString
- https://github.com/shuaijia/RichTextView
- 我的微信公众号——安卓干货营
那接下来就先看下效果图
今天会简单介绍几个Span的基本用法,也会分享一些比较酷炫的使用方法:
- 设置字体颜色
- 改变字体背景色
- 给文本添加下划线
- 给文本加边框
- 彩虹色文字
- 彩虹色字体渐变动画
- 打字效果展示文本
1、设置字体颜色
/** * 设置不同颜色文字 */private void setForegroundColor() { SpannableString spannableString = new SpannableString( "我爱北京天安门,天安门上太阳升 我爱北京天安门,天安门上太阳升"); spannableString.setSpan(new ForegroundColorSpan(Color.RED), 0, 16, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); tv_diff_color.setText(spannableString);}
2、改变字体背景色
/** * 设置背景色 */private void setBackgroundColor() { SpannableString spannableString = new SpannableString( "我爱北京天安门,天安门上太阳升 我爱北京天安门,天安门上太阳升"); spannableString.setSpan(new BackgroundColorSpan(Color.RED), 0, 16, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); tv_bg_color.setText(spannableString);}
3、给文本添加下划线
/** * 设置超链接 */private void setLink() { SpannableString spannableString = new SpannableString( "我爱北京天安门,天安门上太阳升 我爱北京天安门,天安门上太阳升"); //设置下划线 spannableString.setSpan(new UnderlineSpan(), 0, 16, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); tv_link.setText(spannableString);}
4、给文本加边框
这种效果就不再是简单的直接使用系统提供的Span类就可以了,需要我们自定义:
public class FrameSpan extends ReplacementSpan { private final Paint mPaint; private int mWidth; public FrameSpan() { mPaint = new Paint(); mPaint.setStyle(Paint.Style.STROKE); mPaint.setColor(Color.RED); mPaint.setAntiAlias(true); } @Override public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { //return text with relative to the Paint mWidth = (int) paint.measureText(text, start, end); return mWidth; } @Override public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { //draw the frame with custom Paint canvas.drawRect(x, top, x + mWidth, bottom, mPaint); canvas.drawText(text, start, end, x, y, paint); }}
类似于自定义View,最重要的是在初始化画笔、获取绘制区域大小、在draw中绘制矩形边框。
这里就不再重复累赘了。
然后和之前类似,使用它:
/** * 给文字加边框 */private void addBox() { SpannableString spannableString = new SpannableString( "我爱北京天安门,天安门上太阳升 我爱北京天安门,天安门上太阳升"); spannableString.setSpan(new FrameSpan(), 0, 7, Spanned.SPAN_INCLUSIVE_INCLUSIVE); tv_biankuang.setText(spannableString);}
5、彩虹色文字
自定义Span:
public class RainbowSpan extends CharacterStyle implements UpdateAppearance { private int[] colors; public RainbowSpan(Context context) { colors = context.getResources().getIntArray(R.array.splash_bg); } @Override public void updateDrawState(TextPaint paint) { paint.setStyle(Paint.Style.FILL); Shader shader = new LinearGradient(0, 0, 0, paint.getTextSize() * colors.length, colors, null, Shader.TileMode.MIRROR); Matrix matrix = new Matrix(); matrix.setRotate(90); shader.setLocalMatrix(matrix); paint.setShader(shader); }}
其中CharSequence是一组可读的Char序列,提供了操作Char序列的接口,是所有Span类的根父类。
使用Shader进行着色渲染,LinearGradient是线性渐变,Gradient是基于Shader类,所以我们通过Paint的setShader方法来设置这个渐变.
LinearGradient参数含义:
- X0: 渐变起初点坐标x位置
- y0: 渐变起初点坐标y位置
- x1: 渐变终点坐标x位置
- y1: 渐变终点坐标y位置
- color0: 渐变开始颜色
- color1: 渐变结束颜色
- tile: 平铺方式
然后使用
/** * 设置彩色字体 */private void setColofulText() { SpannableString spannableString = new SpannableString( "我爱北京天安门,天安门上太阳升 我爱北京天安门,天安门上太阳升"); spannableString.setSpan(new RainbowSpan(this), 0, 15, Spanned.SPAN_INCLUSIVE_INCLUSIVE); tv_color.setText(spannableString);}
6、彩虹色文字动起来
和上一步相比,不同的是,需实时更新、重绘彩色,所以,自定义的Span类相比于上一个RainbowSpan来说,主要有以下不同:
- 声明变量—— 横向渐变的百分比translateXPercentage,并设置对应get、set方法;
- 在updateDrawState中使用matrix.postTranslate进行变化;
- postTranslate是指在setRotate后平移。
public class AnimatedColorSpan extends CharacterStyle implements UpdateAppearance { private final int[] colors; private Shader shader = null; private Matrix matrix = new Matrix(); private float translateXPercentage = 0; public AnimatedColorSpan(Context context) { colors = context.getResources().getIntArray(R.array.splash_bg); } public void setTranslateXPercentage(float percentage) { translateXPercentage = percentage; } public float getTranslateXPercentage() { return translateXPercentage; } @Override public void updateDrawState(TextPaint paint) { paint.setStyle(Paint.Style.FILL); float width = paint.getTextSize() * colors.length; if (shader == null) { shader = new LinearGradient(0, 0, 0, width, colors, null, Shader.TileMode.MIRROR); } matrix.reset(); matrix.setRotate(90); matrix.postTranslate(width * translateXPercentage, 0); shader.setLocalMatrix(matrix); paint.setShader(shader); }}
然后使用:
/** * 设置彩色动画 */private void setColofulAnimText() { final SpannableString spannableString = new SpannableString( "我爱北京天安门,天安门上太阳升 我爱北京天安门,天安门上太阳升"); AnimatedColorSpan span = new AnimatedColorSpan(this); spannableString.setSpan(span, 0, 15, 0); // 设置动画 ObjectAnimator objectAnimator = ObjectAnimator.ofFloat( span, ANIMATED_COLOR_SPAN_FLOAT_PROPERTY, 0, 100); objectAnimator.setEvaluator(new FloatEvaluator()); objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { tv_color_anim.setText(spannableString); } }); objectAnimator.setInterpolator(new LinearInterpolator()); objectAnimator.setDuration(DateUtils.MINUTE_IN_MILLIS * 2); objectAnimator.setRepeatCount(ValueAnimator.INFINITE); objectAnimator.start();}
大家可能注意到了,设置动画时用到了动画属性变化器:
/** * 彩色动画 属性变化器 */private static final Property<AnimatedColorSpan, Float> ANIMATED_COLOR_SPAN_FLOAT_PROPERTY = new Property<AnimatedColorSpan, Float>(Float.class, "ANIMATED_COLOR_SPAN_FLOAT_PROPERTY") { @Override public void set(AnimatedColorSpan span, Float value) { span.setTranslateXPercentage(value); } @Override public Float get(AnimatedColorSpan span) { return span.getTranslateXPercentage(); }};
在变化器的对应方法中设置Span变化的百分比。
7、文本实现打字效果
先看看Span的写法:
public class MutableForegroundColorSpan extends CharacterStyle implements UpdateAppearance { private int mColor = Color.BLACK; private int mAlpha = 0 ; @Override public void updateDrawState(TextPaint tp) { tp.setColor(mColor); tp.setAlpha(mAlpha); } public int getColor() { return mColor; } public void setColor(int color) { this.mColor = color; } public void setAlpha(int alpha) { mAlpha = alpha; }}
public class TypeWriterSpanGroup { private final float mAlpha; private final ArrayList<MutableForegroundColorSpan> mSpans; public TypeWriterSpanGroup(float alpha) { mAlpha = alpha; mSpans = new ArrayList<MutableForegroundColorSpan>(); } public void addSpan(MutableForegroundColorSpan span) { span.setAlpha((int) (mAlpha * 255)); mSpans.add(span); } public void setAlpha(float alpha) { int size = mSpans.size(); float total = 1.0f * size * alpha; for(int index = 0 ; index < size; index++) { MutableForegroundColorSpan span = mSpans.get(index); if(total >= 1.0f) { span.setAlpha(255); total -= 1.0f; } else { span.setAlpha((int) (total * 255)); total = 0.0f; } } } public float getAlpha() { return mAlpha; }}
思路是这样的,每打印一个文字,都是一个对应的MutableForegroundColorSpan,要想实现连续的打印每个字,我们需要创建一个集合来存放所有得Span。
循环集合中所有的Span,除了最近一个打印的字以外,其他的字设置为不透明,第一个跟随动画进行渐变。
看下动画的使用:
/** * 打字效果 */private void addTyping() { String content = "我爱北京天安门,天安门上太阳升 我爱北京天安门,天安门上太阳升"; final SpannableString spannableString = new SpannableString(content); // 添加Span final TypeWriterSpanGroup group = new TypeWriterSpanGroup(0); for (int index = 0; index <= content.length() - 1; index++) { MutableForegroundColorSpan span = new MutableForegroundColorSpan(); group.addSpan(span); spannableString.setSpan(span, index, index + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } // 添加动画 ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(group, TYPE_WRITER_GROUP_ALPHA_PROPERTY, 0.0f, 1.0f); objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //refresh tv_dazi.setText(spannableString); } }); objectAnimator.setDuration(5000); objectAnimator.setRepeatCount(ValueAnimator.INFINITE); objectAnimator.start();}
还有变化器:
/** * 打字动画 属性变化器 */private static final Property<TypeWriterSpanGroup, Float> TYPE_WRITER_GROUP_ALPHA_PROPERTY = new Property<TypeWriterSpanGroup, Float>(Float.class, "TYPE_WRITER_GROUP_ALPHA_PROPERTY") { @Override public void set(TypeWriterSpanGroup spanGroup, Float value) { spanGroup.setAlpha(value); } @Override public Float get(TypeWriterSpanGroup spanGroup) { return spanGroup.getAlpha(); }};
关于使用Span实现TextView的几种效果,大致就介绍到这,有错误的地方和不足的地方,希望大家提出,我们一起进步^_^。
更多精彩内容,请关注我的微信公众号——安卓干货营。
- 使用Span实现各种酷炫效果
- Span使用之利用系统Span样式实现模糊搜索,匹配变色的特殊UI效果
- Span使用之利用自定义Span解析Html中特殊标签实现类似微博@效果
- 自定义Toast实现各种炫酷效果
- android学习笔记---59_各种图形的使用介绍,android炫酷效果的实现
- Android学习笔记_42_各种图形的炫酷效果的实现和使用
- 使用SpannableString实现字体的各种效果
- js实现span文本选中效果
- 使用CoordinatorLayout打造各种炫酷的效果
- 使用CoordinatorLayout打造各种炫酷的效果
- 使用CoordinatorLayout打造各种炫酷的效果
- 使用CoordinatorLayout打造各种炫酷的效果
- cocos2d-x 使用action实现各种动画效果
- 使用 MARQUEE HTML中实现图片的各种滚动效果
- cocos2d-x 使用action实现各种动画效果
- cocos2d-x 使用action实现各种动画效果
- cocos2d-x 使用action实现各种动画效果 .
- PHP中使用Imagick实现各种图片效果实例
- Qt运行cmd命令
- webshell 搭建
- Android程序员搭建一个属于自己的服务器
- 减少用户投诉,就选中国移动二次号查询
- JS中break continue和return的用法
- 使用Span实现各种酷炫效果
- oracle性能优化建议
- Android工作两年之后的第一个App--天真无谐
- 如何在 Vue-cli 创建的项目中引入 iView组件UI
- 游戏编程
- Glide 一个专注于平滑滚动的图片加载和缓存库
- 如何给eclipse在线安装Git插件EGit
- 关于Bunner简单框架加载网络图片轮播。
- 三子棋游戏