android 绘制动态字,文字动次打次,让文字动态绘制出来

本文详细介绍了如何在Android中利用Canvas和PathMeasure创建文字轮廓动画。通过getTextPath方法获取文本的Path,然后使用PathMeasure进行分段绘制,实现文字的动态显示。通过属性动画控制Path的绘制进度,达到平滑的动画效果。文章还讨论了如何优化动画速度,使其保持匀速。最后,展示了关键代码实现和CanvasView的onDraw方法。
摘要由CSDN通过智能技术生成

本文属于Android技术论述文章,阅读完大致需要五分钟

原创文章,转载请注明出处。

没时间的小伙伴可以直接跳过文章,点击项目地址,如果喜欢的话,顺手给个star那是极好的【娇羞……】

二话不说,效果奉上!

fd6b22f612015917bbafa58ec8d2d563.gif

知识点序列:

Canvas绘制

TextPaint

Path

PathMeasure【测量Path】

代码分析

获取文字的轮廓Path

在TextPaint中有这样一个方法,getTextPath,如下:

public void getTextPath(String text, int start, int end,

float x, float y, Path path) {

if ((start | end | (end - start) | (text.length() - end)) < 0) {

throw new IndexOutOfBoundsException();

}

nGetTextPath(mNativePaint, mNativeTypeface, mBidiFlags, text, start, end, x, y,

path.mutateNI());

}

复制代码

👀其中nGetTextPath里面是调用了一个原生函数,具体实现不必理会。只需要了解函数的各个参数就可以了。

参数含义:

text:文本内容

start:需要测量的文本中的第一个字符的下标

end:需要测量的文本最后一个字符的下标加1

x:Path起点的坐标X

y:Path起点的坐标Y

path:最终测量得到的Path

Path分段绘制

PathMeasure这个类可以说是Path相关的工具解析类,里面大多是原生函数,实现细节不必深究。只需要会使用方法即可。 第一步我们得到文字的轮廓Path之后,这一步将此path按段绘制出来即可。在代码中,由CanvasView这个类来具体实现绘制的详尽流程。看代码,将文本轮廓Path设置进来:

// 保留一份原始Path,用作绘制最终填色的文字

mOrignalPath = orignalPath;

if (null == mPathMeasure) {

mPathMeasure = new PathMeasure();

}

//先重置一下需要显示动画的path

mAnimPath.reset();

mAnimPath.moveTo(0, 0);

mPathMeasure.setPath(orignalPath, false);

// getLength()方法获得的是当前path的长度;而nextContour()方法是将Path切换到下一段Path,多应用在复杂path中

mTextCount = 0;

// 计算文字总共有多少段Path

while (mPathMeasure.nextContour()) {

mTextCount++;

}

// PathMeasure重新设置一次

mPathMeasure.setPath(orignalPath, false);

mPaint.setStyle(Paint.Style.STROKE);

复制代码

其中成员变量mAnimPath,即是用在onDraw()方法内用于绘制的Path。我们会不停地通过PathMeasure刷新这个Path,用于动画流畅运行。

接下来是引擎代码,使用的是属性动画,看代码实现:

if (null == mValueAnimator) {

// 如果一个文本Path包含n个小Path,那么属性动画会Repeat运行n次,每一段小path默认动画时间为900ms

mValueAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);

mValueAnimator.setDuration(900);

mValueAnimator.setInterpolator(new LinearInterpolator());

}

// 引擎无限次重复发动

mValueAnimator.setRepeatCount(ValueAnimator.INFINITE);

mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

float value = (float) animation.getAnimatedValue();

// 将一段小Path从0%到100%赋值到mAnimPath中,调用重绘

mPathMeasure.getSegment(0, mPathMeasure.getLength() * value, mAnimPath, true);

invalidate();

}

});

mValueAnimator.addListener(new AnimatorListenerAdapter() {

@Override

public void onAnimationRepeat(Animator animation) {

super.onAnimationRepeat(animation);

//绘制完一条Path之后,再绘制下一条,直到完成为止。

if (!mPathMeasure.nextContour()) {

animation.end();

}

invalidate();

}

});

复制代码

注释里具体原因亦已写明。这种引擎的设置,就是每一小段Path不管长短,其绘制时间都是相等的,会造成动画看起来时慢时快。

其实要让动画一直匀速跑起来也很容易,就是提前将原始Path测量一遍,设置一个总时间,然后根据小Path的长短来按照比例分配时间。这样即可使动画匀速进行。具体代码不再多言😘,有兴趣的小伙伴可以试试。

再看看CanvasView内的onDraw()方法实现:

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

if (null != mPathMeasure && mPathMeasure.getLength() == 0) {

mPaint.setStyle(Paint.Style.FILL);

canvas.drawPath(mOrignalPath, mPaint);

return;

}

canvas.drawPath(mAnimPath, mPaint);

}

复制代码

这里面的代码更加简单,在Path绘制完之前,一直绘制mAnimPath即可。Path绘制完之后,设置画笔的绘制风格,将文字空白处填上色即可。

以上。就是本次项目的主要思路解析。大家走过路过不要错过,给添个Star呗😄。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值