【开源项目解析】背景有波浪效果的TextView

Hello,好久没写文章了,有木有想我呀~ 正式工作已经过去一个月了,发现在青岛实习和在北京工作,感觉完全不一样呢~ 现在每天晚上回到住的地方,都累的想睡觉…所以也没心情写太多文章和大家分享了,不过我会尽快调整状态,重振雄风的!(哪里起来怪怪的…)

项目介绍

这篇文章,会介绍一个开源项目,叫做Titanic,是的,中文名就叫“泰坦尼克”…

下面是项目地址 https://github.com/RomainPiel/Titanic

要实现的效果是下面这样滴

我的想法

如果你是一个程序员,那么在你第一眼看到这个效果的时候,你可能会想,如果我要实现类似的效果,应该怎么做呢?

我不知道你们会有什么样的思路,我第一眼看到的时候,我想起了PorterDuffXfermode,前面是一张文字的图片,后面一张波浪的图片,然后设置相交模式,从而出现这种文字和图片的交叉效果,不断的改变后面图片位置,实现动态的效果。

当然,我只是想了一想,然后就抱着这个想法看源码去了,看完源码才发现,作者的实现思路更加的NB~通过BitmapShader实现了这种效果,下面,我会参照源码,给你介绍一下实现思路,非常简单,不要眨眼哦~

实现思路

Titanic这个项目非常的简单,只有两个类,分别是Titanic和TitanicTextView,那么如何使用呢?非常简单:

TitanicTextView tv = (TitanicTextView) findViewById(R.id.my_text_view);tv.setTypeface(Typefaces.get(this, “Satisfy-Regular.ttf”));new Titanic().start(tv);

如果你不想设置特殊字体,那么中间的代码删除也可以,两行代码搞定,是不是非常easy~

那么Titanic这个类是干嘛的呢?

为了方便理解和观看,我将不重要代码省略了,你可以对照源码观看 我们调用了Titanic的start()之后,就执行了下面的代码了:

(final TitanicTextView textView) {final Runnable animate = new Runnable() {() {textView.setSinking(true);// horizontal animation. 200 = wave.png widthObjectAnimator maskXAnimator = ObjectAnimator.ofFloat(textView, “maskX”, 0, 200);maskXAnimator.setRepeatCount(ValueAnimator.INFINITE);maskXAnimator.setDuration(1000);maskXAnimator.setStartDelay(0);int h = textView.getHeight();ObjectAnimator maskYAnimator = ObjectAnimator.ofFloat(textView, “maskY”, h/2, – h/2);maskYAnimator.setRepeatCount(ValueAnimator.INFINITE);maskYAnimator.setRepeatMode(ValueAnimator.REVERSE);maskYAnimator.setDuration(10000);maskYAnimator.setStartDelay(0);// now play both animations togetheranimatorSet = new AnimatorSet();animatorSet.playTogether(maskXAnimator, maskYAnimator);animatorSet.setInterpolator(new LinearInterpolator());animatorSet.addListener(new Animator.AnimatorListener() {(Animator animation) {}(Animator animation) {textView.setSinking(false);if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {textView.postInvalidate();} else {textView.postInvalidateOnAnimation();}animatorSet = null;}省略…});if (animatorListener != null) {animatorSet.addListener(animatorListener);}animatorSet.start();}if (!textView.isSetUp()) {textView.setAnimationSetupCallback(new TitanicTextView.AnimationSetupCallback() {(final TitanicTextView target) {animate.run();}});} else {animate.run();}};

这段代码是不是非常简单?但是有点奇怪啊,里面为什么声明Runnable对象呢?而且这里没开线程啊,而是直接调用的run(),好诡异的代码!

其实这个不需要多想,作者只不过是为了代码复用,所用把需要的代码放在run()方法,方便调用,但是这个代码风格我并不喜欢,因为这会让其他阅读代码的人产生误会,比如我就为了这一块代码,想了半个多小时他为什么这样写…

我们看不惯,就可以改成下面的这种方式:

(final TitanicTextView textView) {if (!textView.isSetUp()) {textView.setAnimationSetupCallback(new TitanicTextView.AnimationSetupCallback() {(final TitanicTextView target) {run(textView);}});} else {run(textView);}}(final TitanicTextView textView) {textView.setSinking(true);ObjectAnimator maskXAnimator = ObjectAnimator.ofFloat(textView, “maskX”, 0, 200);maskXAnimator.setRepeatCount(ValueAnimator.INFINITE);maskXAnimator.setDuration(1000);maskXAnimator.setStartDelay(0);int h = textView.getHeight();ObjectAnimator maskYAnimator = ObjectAnimator.ofFloat(textView, “maskY”, h / 2, -h / 2);maskYAnimator.setRepeatCount(ValueAnimator.INFINITE);maskYAnimator.setRepeatMode(ValueAnimator.REVERSE);maskYAnimator.setDuration(10000);maskYAnimator.setStartDelay(0);// now play both animations togetheranimatorSet = new AnimatorSet();animatorSet.playTogether(maskXAnimator, maskYAnimator);animatorSet.setInterpolator(new LinearInterpolator());animatorSet.addListener(new Animator.AnimatorListener() {(Animator animation) {}(Animator animation) {textView.setSinking(false);if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {textView.postInvalidate();} else {textView.postInvalidateOnAnimation();}animatorSet = null;}(Animator animation) {}(Animator animation) {}});animatorSet.start();}当一个人把寂寞当作人生预约的美丽,

【开源项目解析】背景有波浪效果的TextView

相关文章:

你感兴趣的文章:

标签云: