// startValue、endValue:动画的初始值和结束值
… // 写入对象动画过渡的逻辑
return value;
// 返回对象动画过渡的逻辑计算后的值
}
2) ObjectAnimator
:直接对对象的属性值进行改变操作,从而实现动画效果
ObjectAnimator
继承自ValueAnimator
类,底层的动画实现机制还是基本值的改变。它是不断控制值的变化,再不断自动赋给对象的属性,从而实现动画效果。这里的自动赋值,是通过调用对象属性的set/get方法进行自动赋值,属性动画初始值如果有就直接取,没有则调用属性的get()方法获取,当值更新变化时,通过属性的set()方法进行赋值。每次赋值都是调用view的postInvalidate()/invalidate()
方法不断刷新视图(实际调用了onDraw()
方法进行了重绘视图)。
//Object 需要操作的对象; propertyName 需要操作的对象的属性; values动画初始值&结束值,
//如果是两个值,则从a->b值过渡,如果是三值,则从a->b->c
ObjectAnimator animator = ObjectAnimator.ofFloat(Object object, String propertyName, float …values);
如果采用ObjectAnimator
类实现动画,操作的对象的属性必须有get()和set()方法。
其他用法:
1)AnimatorSet组合动画
AnimatorSet.play(Animator anim) :播放当前动画
AnimatorSet.after(long delay) :将现有动画延迟x毫秒后执行
AnimatorSet.with(Animator anim) :将现有动画和传入的动画同时执行
AnimatorSet.after(Animator anim) :将现有动画插入到传入的动画之后执行
AnimatorSet.before(Animator anim) : 将现有动画插入到传入的动画之前执行
2) ViewPropertyAnimator直接对属性操作,View.animate()返回的是一个ViewPropertyAnimator对象,之后的调用方法都是基于该对象的操作,调用每个方法返回值都是它自身的实例
View.animate().alpha(0f).x(500).y(500).setDuration(500).setInterpolator()
3)设置动画监听
Animation.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animation animation) {
//动画开始时执行
}
@Override
public void onAnimationRepeat(Animation animation) {
//动画重复时执行
}
@Override
public void onAnimationCancel()(Animation animation) {
//动画取消时执行
}
@Override
public void onAnimationEnd(Animation animation) {
//动画结束时执行
}
});
2、补间动画实现原理
主要有四种AlpahAnimation
\ ScaleAnimation
\ RotateAnimation
\ TranslateAnimation
四种,对透明度、缩放、旋转、位移四种动画。在调用View.startAnimation
时,先调用View.setAnimation(Animation)
方法给自己设置一个Animation对象,再调用invalidate来重绘自己。在View.draw(Canvas, ViewGroup, long)方法中进行了getAnimation()
, 并调用了drawAnimation(ViewGroup, long, Animation, boolean)
方法,此方法调用Animation.getTranformation()
方法,再调用applyTranformation()
方法,该方法中主要是对Transformation.getMatrix().setTranslate/setRotate/setAlpha/setScale
来设置相应的值,这个方法系统会以60FPS
的频率进行调用。具体是在调Animation.start()方法中会调用animationHandler.start()
方法,从而调用了scheduleAnimation()
方法,这里会调用mChoreographer.postCallback(Choregrapher.CALLBACK_ANIMATION, this, null)
放入事件队列中,等待doFrame()
来消耗事件。
当一个 ChildView
要重画时,它会调用其成员函数 invalidate() 函数将通知其 ParentView
这个 ChildView
要重画,这个过程一直向上遍历到 ViewRoot
,当 ViewRoot
收到这个通知后就会调用ViewRoot
中的 draw 函数从而完成绘制。View::onDraw() 有一个画布参数 Canvas, 画布顾名思义就是画东西的地方,Android 会为每一个 View 设置好画布,View 就可以调用 Canvas 的方法,比如:drawText
, drawBitmap
, drawPath
等等去画内容。每一个 ChildView
的画布是由其 ParentView
设置的,ParentView
根据 ChildView
在其内部的布局来调整 Canvas,其中画布的属性之一就是定义和 ChildView
相关的坐标系,默认是横轴为 X 轴,从左至右,值逐渐增大,竖轴为 Y 轴,从上至下,值逐渐增大。
Android 补间动画就是通过 ParentView
来不断调整 ChildView
的画布坐标系来实现的,在ParentView
的dispatchDraw
方法会被调用。
dispatchDraw()
{
…
Animation a = ChildView.getAnimation()
Transformation tm = a.getTransformation();
Use tm to set ChildView’s Canvas;
Invalidate();
…
}
这里有两个类:Animation 和 Transformation,这两个类是实现动画的主要的类,Animation 中主要定义了动画的一些属性比如开始时间、持续时间、是否重复播放等,这个类主要有两个重要的函数:getTransformation
和 applyTransformation
,在 getTransformation
中 Animation 会根据动画的属性来产生一系列的差值点,然后将这些差值点传给 applyTransformation
,这个函数将根据这些点来生成不同的 Transformation,Transformation 中包含一个矩阵和 alpha 值,矩阵是用来做平移、旋转和缩放动画的,而 alpha 值是用来做 alpha 动画的(简单理解的话,alpha 动画相当于不断变换透明度或颜色来实现动画),调用 dispatchDraw
时会调用 getTransformation
来得到当前的 Transformation。某一个 View 的动画的绘制并不是由他自己完成的而是由它的父 view 完成。
补间动画TranslateAnimation,View位置移动了,可是点击区域还在原来的位置,为什么?
View在做动画是,根据动画时间的插值,计算出一个Matrix,不停的invalidate,在onDraw中的Canvas上使用这个计算出来的Matrix去draw view的内容。
某个view的动画绘制并不是由它自己完成,而是由它的父view完成,使它的父view画布进行了移动,而点击时还是点击原来的画布。使得它看起来变化了。
3、Android各个版本API的区别
主要记住一些大版本变化:
-
android3.0 代号Honeycomb, 引入Fragments, ActionBar,属性动画,硬件加速
-
android4.0 代号Ice Cream,API14:截图功能,人脸识别,虚拟按键,3D优化驱动
-
android5.0 代号Lollipop API21:调整桌面图标及部件透明度等
-
android6.0 代号M Marshmallow API23,软件权限管理,安卓支付,指纹支持,App关联,
-
android7.0 代号N Preview API24,多窗口支持(不影响Activity生命周期),增加了JIT编译器,引入了新的应用签名方案APK Signature Scheme v2(缩短应用安装时间和更多未授权APK文件更改保护),严格了权限访问
-
android8.0 代号O API26,取消静态广播注册,限制后台进程调用手机资源,桌面图标自适应
-
android9.0 代号P API27,加强电池管理,系统界面添加了Home虚拟键,提供人工智能API,支持免打扰模式
4、Requestlayout,onlayout,onDraw,DrawChild区别与联系
requestLayout()
方法 :会导致调用measure()过程 和 layout()过程 。 说明:只是对View树重新布局layout过程包括measure()和layout()过程,如果view的l,t,r,b没有必变,那就不会触发onDraw
;但是如果这次刷新是在动画里,mDirty非空,就会导致onDraw
。
onLayout()
方法(如果该View是ViewGroup
对象,需要实现该方法,对每个子视图进行布局)
onDraw()
方法绘制视图本身 (每个View都需要重载该方法,ViewGroup
不需要实现该方法)
drawChild()
去重新回调每个子视图的draw()方法
5、invalidate和postInvalidate的区别及使用
View.invalidate()
: 层层上传到父级,直到传递到ViewRootImpl
后触发了scheduleTraversals()
,然后整个View树开始重新按照View绘制流程进行重绘任务。
invalidate
:在ui线程刷新view
postInvalidate
:在工作线程刷新view(底层还是handler)其实它的原理就是invalidate+handler
View.postInvalidate
最终会调用ViewRootImpl.dispatchInvalidateDelayed()
方法
public void dispatchInvalidateDelayed(View view, long delayMilliseconds) {
Message msg = mHandler.obtainMessage(MSG_INVALIDATE, view);
mHandler.sendMessageDelayed(msg, delayMilliseconds);
}
这里的mHandler
是ViewRootHandler
实例,在该Handler的handleMessage
方法中调用了view.invalidate()方法。
case MSG_INVALIDATE:
((View) msg.obj).invalidate();
break;
6、Activity-Window-View三者的差别
Activity:是安卓四大组件之一,负责界面展示、用户交互与业务逻辑处理;
Window:就是负责界面展示以及交互的职能部门,就相当于Activity的下属,Activity的生命周期方法负责业务的处理;
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
总结
最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2019-2021面试真题解析,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。
还有 高级架构技术进阶脑图、Android开发面试专题资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
2021年虽然路途坎坷,都在说Android要没落,但是,不要慌,做自己的计划,学自己的习,竞争无处不在,每个行业都是如此。相信自己,没有做不到的,只有想不到的。祝大家2021年万事大吉。
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
到的。祝大家2021年万事大吉。
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-bZ4YVxfA-1712757950043)]