在日常开发中,经常会遇到各种视觉效果,有的效果可能一眼看去会让人觉得很复杂,但是我们必须明确一点:
所有复杂动效都是可以分解成单一的基础动作,比如缩放,平移,旋转这些基础单元,然后将所有基础单元动作进行组合,就会产生让人眼前一亮的视觉动效。
首先看下下图效果:
按照上面我们提到的思路进行分解:
Logo的名称LitePlayer被拆分为单个文字 所有文字随机打散在屏幕各个位置 中间的Logo被隐藏 Logo文字从随机位置平移到页面固定位置 中间的Logo图片逐渐显示,并且附带从下往上平移一小段位移 Logo被打散的文字组合成名称 Logo组合成名称后,有个渐变的光晕照射效果从左往右移动 动画结束
当我们把动画拆解后,就可以针对每个拆解单元去构造实现方案了。
实现
==============================================================
首先我们先对logo文字动画进行实现:
1. 首先对于数据来源,我们期望传入一个logo的字符串,内部将字符串拆解为单个文字数组:
// fill the text to array
private void fillLogoTextArray(String logoName) {
if (TextUtils.isEmpty(logoName)) {
return;
}
if (mLogoTexts.size() > 0) {
mLogoTexts.clear();
}
for (int i = 0; i < logoName.length(); i++) {
char c = logoName.charAt(i);
mLogoTexts.put(i, String.valueOf©);
}
}
2. 所有文字需要随机打散在屏幕各个位置,因为涉及到坐标,我们可以在onSizeChanged中进行logo文字随机位置的初始化,同时我们构建两个集合存储每个文字被打散和组合后的坐标状态:
// 最终合成logo后的坐标
private SparseArray mQuietPoints = new SparseArray<>();
// logo被随机打散的坐标
private SparseArray mRadonPoints = new SparseArray<>();
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
initLogoCoordinate();
}
private void initLogoCoordinate() {
float centerY = mHeight / 2f + mPaint.getTextSize() / 2 + mLogoOffset;
// calculate the final xy of the text
float totalLength = 0;
for (int i = 0; i < mLogoTexts.size(); i++) {
String str = mLogoTexts.get(i);
float currentLength = mPaint.measureText(str);
if (i != mLogoTexts.size() - 1) {
totalLength += currentLength + mTextPadding;
} else {
totalLength += currentLength;
}
}
// the draw width of the logo must small than the width of this AnimLogoView
if (totalLength > mWidth) {
throw new IllegalStateException(“This view can not display all text of logoName, please change text size.”);
}
float startX = (mWidth - totalLength) / 2;
if (mQuietPoints.size() > 0) {
mQuietPoints.clear();
}
for (int i = 0; i < mLogoTexts.size(); i++) {
String str = mLogoTexts.get(i);
float currentLength = mPaint.measureText(str);
mQuietPoints.put(i, new PointF(startX, centerY));
startX += currentLength + mTextPadding;
}
// generate random start xy of the text
if (mRadonPoints.size() > 0) {
mRadonPoints.clear();
}
// 构建随机初始坐标
for (int i = 0; i < mLogoTexts.size(); i++) {
mRadonPoints.put(i, new PointF((float) Math.random() * mWidth, (float) Math.random() * mHeight));
}
}
3. 构建动画过程,定义一个属性动画从0-1计算进度,在动画过程通过重绘实现文字从凌乱打散的坐标到最终组合坐标进行移动:
// init the translation animation
private void initOffsetAnimation() {
mOffsetAnimator = ValueAnimator.ofFloat(0, 1);
mOffsetAnimator.setDuration(mOffsetDuration);
mOffsetAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
mOffsetAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
if (mQuietPoints.size() <= 0 || mRadonPoints.size() <= 0) {
return;
}
mOffsetAnimProgress = (float) animation.getAnimatedValue();
invalidate();
}
});
}
@Override
protected void onDraw(Canvas canvas) {
if (!isOffsetAnimEnd) {// offset animation
本文在开源项目:Android开发不会这些?如何面试拿高薪! 中已收录,里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频 如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img-Zf1iQVlu-1710962203889)] [外链图片转存中…(img-rxdMETHN-1710962203889)] [外链图片转存中…(img-5ODoBizJ-1710962203890)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频 如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android) [外链图片转存中…(img-4qMu8qtn-1710962203891)]
参考阅读
发表评论