Android仿58同城加载动画
龙旋
共 5606字,需浏览 12分钟
· 2022-01-16
效果图:
分析动画
首先分析动画,如上图所示:
动画分为三部分,分别为上方跳动部分,中间阴影部分,和下方文字部分:
上方跳动部分,三个几何图形,实现上抛下落(平移),上抛过程中几何图形进行旋转,到达最底部时,变换几何图形
中间阴影部分,一个椭圆,进行缩放
下方文字部分居中
进行绘制
主要运用Drawable动画进行绘制。
public class ShapeLoadingDrawable extends Drawable implements Animatable{
}
先将上方部分三个几何图和中间部分椭圆形绘制出来
//画圆
private void drawCircle(Canvas canvas) {
mPaint.setColor(Color.parseColor("#aa738ffe"));
canvas.drawCircle(mWidth / 2, mHeight / 2, radius, mPaint);
}
//画正方形
private void drawRect(Canvas canvas) {
mPaint.setColor(Color.parseColor("#aae84e49"));
canvas.drawRect(mWidth / 2 -rectLength/2, mHeight / 2 - rectLength/2, mWidth / 2 + rectLength/2, mHeight / 2 + rectLength/2, mPaint);
}
//画三角形
private void drawTriangle(Canvas canvas) {
mPaint.setColor(Color.parseColor("#aa72d572"));
Path path = new Path();
path.moveTo(mWidth / 2, mHeight / 2 - rectLength/2);
path.lineTo((float) (mWidth / 2 - Math.sqrt(Math.pow(rectLength,2) / 3)), mHeight / 2 + rectLength/2);
path.lineTo((float) (mWidth / 2 + Math.sqrt(Math.pow(rectLength,2) / 3)), mHeight / 2 + rectLength/2);
path.close();
canvas.drawPath(path, mPaint);
}
//画椭圆
private void drawShadow(Canvas canvas) {
mPaint.setColor(Color.parseColor("#25808080"));
canvas.scale(scale, scale, mWidth / 2, mHeight / 2 + 90);
canvas.drawArc(mWidth / 2 - rectLength/2, mHeight / 2 + 80, mWidth / 2 + 50, mHeight / 2 + 100, 0, 360, false, mPaint);
}
进行动画部分代码编写,主要运用ValueAnimator
分析动画:两个部分的动画,一个是上面几何图形的下落上抛动画,一个是中间阴影指示器放大缩小的动画,如果能这样组合就算实现了: 当几何图形下落时配合阴影放大,当几何图形上抛时配合中间阴影缩小。当几何图形下落到最低点时,变换几何图形
/**
* 上抛动画
*/
private void upAnimation() {
final ValueAnimator upAnimation = ValueAnimator.ofFloat(0, -200);
upAnimation.setInterpolator(new DecelerateInterpolator(1.2f));
//为动画设置更新时候的监听
upAnimation.addUpdateListener(new
ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
translateY = (float) upAnimation.getAnimatedValue();
//刷新
invalidateSelf();
}
});
//监听动画结束,进行下落动画
upAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
downAnimation();
}
});
//缩放动画
final ValueAnimator scaleAnimation = ValueAnimator.ofFloat(1, 0.3f);
scaleAnimation.setInterpolator(new DecelerateInterpolator(1.2f));
scaleAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
scale = (float) scaleAnimation.getAnimatedValue();
}
});
//三角形旋转动画
final ValueAnimator rotateTriangleAnimation = ValueAnimator.ofFloat(0, 120);
rotateTriangleAnimation.setInterpolator(new DecelerateInterpolator(1.2f));
rotateTriangleAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
rotateTriangle = (float) rotateTriangleAnimation.getAnimatedValue();
}
});
//正方形旋转动画
final ValueAnimator rotateRectAnimation = ValueAnimator.ofFloat(0, 180);
rotateRectAnimation.setInterpolator(new DecelerateInterpolator(1.2f));
rotateRectAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
rotateRect = (float) rotateRectAnimation.getAnimatedValue();
}
});
upAnimatorSet = new AnimatorSet();
upAnimatorSet.setDuration(300);
upAnimatorSet.playTogether(upAnimation, scaleAnimation, rotateTriangleAnimation, rotateRectAnimation);
upAnimatorSet.start();
}
/**
* 下落动画
*/
private void downAnimation() {
final ValueAnimator downAnimation = ValueAnimator.ofFloat(-200, 0);
downAnimation.setInterpolator(new DecelerateInterpolator(1.2f));
downAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
translateY = (float) downAnimation.getAnimatedValue();
invalidateSelf();
}
});
downAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
upAnimation();
exchangeDraw();
}
});
final ValueAnimator scaleAnimation = ValueAnimator.ofFloat(0.3f, 1);
scaleAnimation.setInterpolator(new DecelerateInterpolator(1.2f));
scaleAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
scale = (float) scaleAnimation.getAnimatedValue();
}
});
downAnimatorSet = new AnimatorSet();
downAnimatorSet.setDuration(500);
downAnimatorSet.playTogether(downAnimation, scaleAnimation);
downAnimatorSet.start();
}
动画使用
在ImageView中设置drawable即可
ShapeLoadingDrawable shapeLoadingDrawable = new ShapeLoadingDrawable();
imageView.setImageDrawable(shapeLoadingDrawable);
shapeLoadingDrawable.start();
到这里就结束啦.
评论
用 Shader 实现旗帜飘扬动画效果
我觉得对于刚入门 3D 编程的朋友来说,如果能够完成代码创建模型数据->创建材质->编写Shader动画这一系列,想必会有满满的成就感。今天就用 Cocos Creator 的 utils.MeshUtils.createMesh 接口,带大家感受一下这个流程。这个流程不仅可以用于新手学
COCOS
2
性能优化——图片压缩、加载和格式选择
大厂技术 高级前端 Node进阶点击上方 程序员成长指北,关注公众号回复1,加入高级Node交流群前言相信大家都听说过 "258 原则(https://blog.csdn.net/weixin_42139375/article/details/8
程序员成长指北
10
同城双活:交易链路的稳定性与可靠性探索 | 得物技术
目录 作者:Alan 英杰 Matt 羊羽 一、背景 1. 异地双活 2. 同城双活 二、设计思路 三、双活整体架构 四、具体改造方案 1. 交易应用侧双活改造 2. 交易依赖方应用双活改造 3. 中间件&基础...
瓜农老梁
0
电子书丨《Android Jetpack应用指南》
▊《Android Jetpack应用指南》叶坤 著电子书售价:39.5元2020年07月出版本书讲解的是Android Jetpack最核心的内容—架构。第1章将对Jetpack做一个大致的介绍。第2章至第9章,将分别详细介绍为搭建MVVM架构而设计...
博文视点Broadview
0
FFmpeg Android 硬件编解码现状及展望
一、功能特性自FFmpeg 6.0版本开始,FFmpeg对Android硬件编解码的支持逐步完善了,当前支持的功能特性包括:通过JNI调用Java MediaCodec直接调用NDK MediaCodec解码:H264、H265、MPEG2、MPEG4、VP8、VP9、AV1编码:...
音视频开发进阶
0
一篇文章教会你使用JS+CSS实现一个简单加载进度条的效果
点击上方“前端进阶学习交流”,进行关注回复“前端”即可获赠前端相关学习资料今日鸡汤老至居人下,春归在客先。大家好,我是前端进阶者,今天给大家来做个小项目,一起来看看吧~一、前言我们经常在网页上 ,游戏界面加...
前端进阶学习交流
0
采集小红书爆款文案,GPT 大模型仿写网页版上线
上个月发布的 GPT 小红书爆款文案生成软件,是一个结合了爬虫数据采集和大模型文案生成的软件,可以全自动将采集的小红书爆款笔记输入大模型,用以生成自己个性化的爆款文案。 有用户付费购买后使用,笑着跟我说这是...
月小水长
0
【赏析】发现一个仿站神器,30分钟做个胡桃里
大家好,我是程序员渔夫。 今天是3.15日,不知道今年的大曝光的APP花落啥家?今天也是我的 小程序 终于破万的日子,mark一下,感谢各位小伙伴的支持。 回归正题,最近在接到一个朋友...
前马上消费_高级安全运维工程师
0