红橙Darren视频笔记 动画讲解 仿58同城 加载动画
参考链接
https://www.jianshu.com/p/e4de28b4d8ac
效果
一.动画分类介绍
帧动画 和 补间动画
帧动画:一张一张的图片不断轮巡播放
补间动画:位移,透明度,像缩放,改变的是View的属性(属性动画属于补间动画)
二.效果分析
2.1 加载显示组合控件(布局) 布局三个部分 = ShapeView + View(阴影背景 shape=“oval”) + TextView
2.2 编写自定view ShapeView
2.3 将布局加载到自定义ViewGroup LoadView中
2.3 分析实现动画
2.3.1第一部分 关于阴影:下落位移的时候配合中间阴影缩小,上抛的时候配合中间阴影放大
2.3.2第二部分 关于形状 1.下落动画+上抛动画 2.差值器,动画速率的问题,下落的时候如果是小球在真实生活中,下落的速度应该是越来越快,上抛的速度应该是越来越慢 3.下落的时候改变形状 4.旋转动画,正方形 180 圆形 三角120
三.性能优化
当后台数据返回的时候我们要把当前页面,设置成 gone (隐藏),只是用代码设置为了隐藏,但是动画View的内存还在跑,怎么办?
释放动画资源
四.部分实现代码
xml部分
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#fff"><com.example.custom58loadview.ShapeViewandroid:id="@+id/shape_view"android:layout_width="40dp"android:layout_height="40dp"android:layout_marginBottom="80dp"android:layout_above="@+id/image_shadow"android:layout_centerInParent="true" /><ImageViewandroid:id="@+id/image_shadow"android:layout_width="50dp"android:layout_height="4dp"android:layout_centerInParent="true"android:layout_margin="15dp"android:src="@drawable/shadow_view" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@+id/image_shadow"android:layout_centerInParent="true"android:layout_marginTop="5dp"android:text="玩命加载中..." /></RelativeLayout><?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello World!"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /><com.example.custom58loadview.CustomLoadViewandroid:id="@+id/load_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true" /></RelativeLayout>
Java部分
public class ShapeView extends View {@ShapeTypeprivate int mCurrentShape = ShapeType.CIRCLE;private Paint mCirclePaint, mTrianglePaint, mSquarePaint;private Path mPath;public ShapeView(Context context) {this(context, null);}public ShapeView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public ShapeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mCirclePaint = initPaintByColor(Color.RED);mTrianglePaint = initPaintByColor(Color.YELLOW);mSquarePaint = initPaintByColor(Color.GRAY);}private Paint initPaintByColor(int color) {Paint paint = new Paint();paint.setAntiAlias(true);paint.setDither(true);paint.setColor(color);return paint;}@Retention(RetentionPolicy.SOURCE)@IntDef({ShapeType.CIRCLE, ShapeType.SQUARE, ShapeType.TRIANGLE})public @interface ShapeType {int CIRCLE = 0;int SQUARE = 1;int TRIANGLE = 2;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int width = MeasureSpec.getSize(widthMeasureSpec);int height = MeasureSpec.getSize(heightMeasureSpec);setMeasuredDimension(Math.min(width, height), Math.min(width, height));}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);switch (mCurrentShape) {case ShapeType.CIRCLE:// 画圆形int center = getWidth() / 2;canvas.drawCircle(center, center, center, mCirclePaint);break;case ShapeType.SQUARE:// 画正方形canvas.drawRect(0, 0, getWidth(), getHeight(), mSquarePaint);break;case ShapeType.TRIANGLE:// 画三角 Path 画路线if (mPath == null) {mPath = new Path();mPath.moveTo(getWidth() >> 1, 0);//勾股定理mPath.lineTo(0, (float) (Math.sqrt(3) * getWidth() / 2));mPath.lineTo(getWidth(), ((float) Math.sqrt(3) * getWidth() / 2));mPath.close();//直接连接到起点}canvas.drawPath(mPath, mTrianglePaint);break;}}public void exchange() {switch (mCurrentShape) {case ShapeType.CIRCLE:mCurrentShape = ShapeType.SQUARE;break;case ShapeType.SQUARE:mCurrentShape = ShapeType.TRIANGLE;break;case ShapeType.TRIANGLE:mCurrentShape = ShapeType.CIRCLE;break;}// 不断重新绘制形状invalidate();}public int getCurrentShape() {return mCurrentShape;}
}public class CustomLoadView extends RelativeLayout {private static final long ANIMATOR_DURATION = 1000;private ShapeView mShapeView;private ImageView mShadowView;private int mShapeTransactionY;//他的值为ShapeView的margin bottompublic CustomLoadView(Context context) {this(context, null);}public CustomLoadView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public CustomLoadView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);inflate(context, R.layout.load_view, this);//上面的这句等价于下面的两句
// LayoutInflater layoutInflater = LayoutInflater.from(context);
// layoutInflater.inflate(R.layout.load_view,this,true);//初始化各个部件 用于后期动画mShapeView = findViewById(R.id.shape_view);mShadowView = findViewById(R.id.image_shadow);mShapeTransactionY = ((MarginLayoutParams) mShapeView.getLayoutParams()).bottomMargin;post(new Runnable() {@Overridepublic void run() {// onResume 之后View绘制流程执行完毕之后(View的绘制流程源码分析那一章)startFullDownAnimate();}});// onCreate() 方法中执行 ,布局文件解析 反射创建实例}//和下落动画相反private void startJumpUpAnimate() {//关于形状的动画// 1.下落动画+上抛动画// 这里是弹起// Y值越大 越在下方ObjectAnimator shapeTransactionAnimate = ObjectAnimator.ofFloat(mShapeView, "translationY", mShapeTransactionY, 0);// 2.差值器,动画速率的问题,下落的时候如果是小球在真实生活中,下落的速度应该是越来越快,上抛的速度应该是越来越慢// 这里是下落DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator();// 3.下落的时候改变形状// mShapeView.exchange();// 4.旋转动画,正方形 180 圆形 三角120float rotationValue = -180;switch (mShapeView.getCurrentShape()) {case ShapeView.ShapeType.SQUARE:rotationValue = -180;break;case ShapeView.ShapeType.TRIANGLE:rotationValue = -120;break;}ObjectAnimator shapeRotateAnimate = ObjectAnimator.ofFloat(mShapeView, "rotation", rotationValue);ObjectAnimator shadowScaleAnimate = ObjectAnimator.ofFloat(mShadowView, "scaleX", 0.3f, 1);//从0.3增加到原有宽度AnimatorSet animatorSet = new AnimatorSet();animatorSet.setDuration(ANIMATOR_DURATION);animatorSet.setInterpolator(decelerateInterpolator);animatorSet.playTogether(shapeTransactionAnimate, shapeRotateAnimate, shadowScaleAnimate);animatorSet.start();//当动画下落完之后就下落了animatorSet.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {// 下落完之后就上抛了startFullDownAnimate();}});}private void startFullDownAnimate() {// 关于阴影的动画 下落位移的时候配合中间阴影缩小,上抛的时候配合中间阴影放大//mShadowView.setScaleX(); //里面的参数的定义可以拿出来直接作为ObjectAnimator.ofFloat的第二个参数 表示动画的类型//关于形状的动画// 1.下落动画+上抛动画// 这里是从高处落下 // Y值越大 越在下方ObjectAnimator shapeTransactionAnimate = ObjectAnimator.ofFloat(mShapeView, "translationY", 0, mShapeTransactionY);// 2.差值器,动画速率的问题,下落的时候如果是小球在真实生活中,下落的速度应该是越来越快,上抛的速度应该是越来越慢// 这里是下落AccelerateInterpolator accelerateInterpolator = new AccelerateInterpolator();// 3.下落的时候改变形状mShapeView.exchange();// 4.旋转动画,正方形 180 圆形 三角120float rotationValue = 0;switch (mShapeView.getCurrentShape()) {case ShapeView.ShapeType.SQUARE:rotationValue = 180;break;case ShapeView.ShapeType.TRIANGLE:rotationValue = 120;break;}ObjectAnimator shapeRotateAnimate = ObjectAnimator.ofFloat(mShapeView, "rotation", rotationValue);ObjectAnimator shadowScaleAnimate = ObjectAnimator.ofFloat(mShadowView, "scaleX", 1, 0.3f);//从原有宽度缩短到0.3AnimatorSet animatorSet = new AnimatorSet();animatorSet.setDuration(ANIMATOR_DURATION);animatorSet.setInterpolator(accelerateInterpolator);animatorSet.playTogether(shapeTransactionAnimate, shapeRotateAnimate, shadowScaleAnimate);// 先执行 translationAnimator 接着执行 scaleAnimator// animatorSet.playSequentially(translationAnimator,scaleAnimator);animatorSet.start();//当动画下落完之后就上抛了animatorSet.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {// 下落完之后就上抛了startJumpUpAnimate();}});}//加载完毕调用 释放动画资源public void loadComplete() {mShapeView.clearAnimation();mShadowView.clearAnimation();// 把LoadingView从父布局移除ViewGroup parent = (ViewGroup) getParent();if (parent != null) {parent.removeView(this);// 从父布局移除removeAllViews();// 移除自己所有的View}}
}
代码
https://github.com/caihuijian/learn_darren_android.git
红橙Darren视频笔记 动画讲解 仿58同城 加载动画相关推荐
- android 仿 动画,Android动画 - 仿58同城加载动画
Android动画 - 仿58同城加载动画 效果图 58LoadingView.gif 分析动画 首先分析动画,如上图所示: 动画分为三部分,分别为上方跳动部分,中间阴影部分,和下方文字部分. 上方跳 ...
- 红橙Darren视频笔记setContentView源码分析 xml加载的过程
setContentView过程分析 从继承Activity的类开始进行分析 MainActivity setContentView(R.layout.activity_main); Activity ...
- android 今日头条加载动画,高仿今日头条加载动画
01 每每浏览手机app时,发现有的效果体验不错,作为一位程序员,总想要是自己来做,怎么实现. 今天我们来模仿今日头条的加载动画. 首先我们来看一下我们这个demo最终效果,有图有真相. 高仿今日头条 ...
- 学习自定义View(二)仿58同城加载
之前用58同城app的时候看到它的加载界面不错,但是那时候还不知道如何实现~接触自定义View后,于是自己试着模仿写了一个 先看效果图: 录制的GIF上有一点卡,其实在真机上面运行很流畅的~ 其实感觉 ...
- 红橙Darren视频笔记 界面优化与屏幕适配(上)
1. 内存泄漏,内存溢出与内存抖动 内存泄漏:GC在内存吃紧去回收内存的时候,无法回收某一块不再使用的内存.随着时间的推移会导致内存溢出,一般是强引用导致 之前有总结过内存泄漏的一些case和解决方案 ...
- 红橙Darren视频笔记 仿QQ侧滑效果
这一篇没有什么新的内容 就是改写 红橙Darren视频笔记 仿酷狗侧滑效果 的侧滑的效果 1.去掉淡入淡出效果 2.加上黑色模板效果 效果: 去掉淡入淡出效果很简单 就是注释掉onScrollChan ...
- 红橙Darren视频笔记 UML图简介
整体架构复制自红橙原视频的课堂笔记 因为他这一课没有博客,所以没有转载链接,CSDN没有转载地址是无法作为转载类型的文章发表的,暂时标记为原创 参考链接 https://blog.csdn.net/r ...
- 红橙Darren视频笔记 代理模式 动态代理和静态代理
红橙Darren视频笔记 代理模式 动态代理和静态代理(Android API 25) 关于代理模式我之前有过相关的介绍: https://blog.csdn.net/u011109881/artic ...
- 红橙Darren视频笔记 类加载机制(API28) 自己写个热修复 查看源码网站
第一部分 类加载机制 一个Activity是如何被Android虚拟机找到的? 在之前的文章 红橙Darren视频笔记 自定义View总集篇(https://blog.csdn.net/u011109 ...
最新文章
- 华人斩获最佳Demo论文,Bengio获时间检验奖,最佳论文突破NLP传统测试方法 | ACL 2020...
- 前端新手学习记录2 -使用vscode编写个人网站首页
- Jenkins持续集成环境之插件管理和角色管理
- 基于visual Studio2013解决C语言竞赛题之0304整除数
- celery-02-安装与使用说明-for-redis
- 法定节假日违规组织培训,51talk被通报批评整改不到位
- 用DotNetOpenAuth实现基于OAuth 2.0的web api授权 (一)Getting Start
- LeetCode 70.爬楼梯(动态规划)
- UVA583 UVALive5406 Prime Factors【素数因子+筛选法】
- 视频教程-轻松搞定Spring全家桶(初识篇)-Java
- Origin 2022b | 更新及安装 | 中英文切换
- BMVC 2020 Keynote 消除数据集偏见
- 30本引进翻译版日本计算机技术书籍推荐
- 看完这一篇,智能家居的坑你至少避开80%(上)
- html文档字符间距怎么设置,Pages字符间距怎么设置 Pages字符间距设置教程
- win10家庭版系统 修改docker为国内镜像
- 华为计算机黑屏怎么办,华为电脑开机屏幕没反应(开机黑屏的3个原因及解决法)...
- 怎么用pdf压缩软件简单实现pdf压缩
- 第十三课 斗地主项目课③游戏音乐与音效及本地存储
- ei eo 功能类型_[转载]CMMI之功能点估算法:EI、EQ和EO