Android实现炫酷文字动画效果
效果展示
实现原理
1. 文字路径的获取
文字路径的获取可以通过Paint的getTextPath方法来获取,
2. PathMeasure+Animator实现动画
这里需要通过PathMeasure的构造方法
PathMeasure(tempPath, false)//通过构造方法
PathMeasure().setPath(tempPath, false)//通过setPath方法
mAnimation = ValueAnimator.ofFloat(0f, 1f)
...省略部分代码
mAnimation!!.addUpdateListener {
mCurrentProcess = it.animatedValue as Float
invalidate()
}
mAnimation!!.start()
mPathMeasure!!.getSegment(0F, mPathMeasure!!.length * mCurrentProcess, mDst, true)//获取路径片段(这里的mDst是用来存储截取出来的路径)
canvas!!.drawPath(mDst, mPaint)//绘制路径
3. 文字的换行问
由于使用自定义View绘制文字它不会主动的去换行因此只能通过我们自己计算来让文字换行
这里我们使用Paint的getTextWidths来获取所有字符的宽度,然后通过循环叠加字符的宽度,每当字符的宽度总和大于控件的宽度时我们便进行换行,这里的换行则是存储下当前遍历到的字符的索引值,然后根据这个索引值对整串字符串进行截取来实现。
val textWidths = FloatArray(mText.length + 1)
mPaint.getTextWidths(mText, 0, mText.length, textWidths)
var tempTextWidthSum = 0f
var tempViewWidth = 0//控件的宽度
...省略部分代码
for (i in 0..(textWidths.size - 1)) {
tempTextWidthSum += textWidths[i]
if (tempTextWidthSum >tempViewWidth ) {
mTextLineCountList.add(i)//存储字符的索引值
tempTextWidthSum = textWidths[i]//因为当前已经比控件宽度大了所以在重新计算的时候需要将这个字符的宽度加进去(因为这已经是第二行了)
}
}
mTextLineCountList.add(mText.length)//将最后的字符索引加进去,不然会缺字
控件的使用
为了方便使用我加了几个自定义属性:
<declare-styleable name="PathAnimTextView">
<!--文字颜色-->
<attr name="animTextColor" format="color"/>
<!--文字大小-->
<attr name="animTextSize" format="float"/>
<!--文字画笔宽度-->
<attr name="animTextStrokWidth" format="float"/>
<!--动画文字-->
<attr name="animText" format="string"/>
<!--动画的速度-->
<attr name="animSpeed">
<!--快-->
<enum name="fast" value="0"/>
<!--慢-->
<enum name="slow" value="1"/>
<!--中速-->
<enum name="medium" value="2"/>
</attr>
<!--字体库的名称-->
<attr name="animTextTypeFace" format="string"/>
<!--文字行间距-->
<attr name="animTextLineMargen" format="float"/>
</declare-styleable>
<com.hehuidai.customview.one.animtextview.PathAnimTextView
android:id="@+id/patv"
app:animTextColor="#ff0000"
app:animTextStrokWidth="2"
app:animTextSize="80"
app:animSpeed="fast"
app:animText="Animation TextView"
app:animTextTypeFace="Muyao-Softbrush.ttf"//这里的字体文件需要放到assets文件中
app:animTextLineMargen="0"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
patv.startTextAnim()
patv.setText("Animation TextView")
评论